]> git.saurik.com Git - wxWidgets.git/blame - src/xpm/scan.c
added tests for filled rects
[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 */
264 if (shapeimage) {
265#ifndef FOR_MSW
e6ed776f 266# ifndef AMIGA
cfbe03c9
JS
267 ErrorStatus = GetImagePixels1(shapeimage, width, height, &pmap,
268 storeMaskPixel);
e6ed776f
GRG
269# else
270 ErrorStatus = AGetImagePixels(shapeimage, width, height, &pmap,
271 storeMaskPixel);
272# endif
cfbe03c9 273#else
ea258ad3
DW
274
275#ifndef __OS2__
cfbe03c9 276 ErrorStatus = MSWGetImagePixels(display, shapeimage, width, height,
e6ed776f 277 &pmap, storeMaskPixel);
ea258ad3
DW
278/* calling convention all messed up OS/2 -- figure out later */
279#endif
280
cfbe03c9
JS
281#endif
282 if (ErrorStatus != XpmSuccess)
283 RETURN(ErrorStatus);
284 }
285
286 /*
287 * scan the image data
ea258ad3 288 *
cfbe03c9
JS
289 * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use optimized
290 * functions, otherwise use slower but sure general one.
ea258ad3 291 *
cfbe03c9
JS
292 */
293
294 if (image) {
295#ifndef FOR_MSW
e6ed776f
GRG
296# ifndef AMIGA
297 if (((image->bits_per_pixel | image->depth) == 1) &&
298 (image->byte_order == image->bitmap_bit_order))
cfbe03c9
JS
299 ErrorStatus = GetImagePixels1(image, width, height, &pmap,
300 storePixel);
e6ed776f
GRG
301 else if (image->format == ZPixmap) {
302 if (image->bits_per_pixel == 8)
303 ErrorStatus = GetImagePixels8(image, width, height, &pmap);
304 else if (image->bits_per_pixel == 16)
305 ErrorStatus = GetImagePixels16(image, width, height, &pmap);
306 else if (image->bits_per_pixel == 32)
307 ErrorStatus = GetImagePixels32(image, width, height, &pmap);
308 } else
cfbe03c9 309 ErrorStatus = GetImagePixels(image, width, height, &pmap);
e6ed776f
GRG
310# else
311 ErrorStatus = AGetImagePixels(image, width, height, &pmap,
312 storePixel);
313# endif
314#else
ea258ad3
DW
315
316#ifndef __OS2__
e6ed776f
GRG
317 ErrorStatus = MSWGetImagePixels(display, image, width, height, &pmap,
318 storePixel);
ea258ad3
DW
319#endif
320
cfbe03c9
JS
321#endif
322 if (ErrorStatus != XpmSuccess)
323 RETURN(ErrorStatus);
324 }
325
326 /*
327 * get rgb values and a string of char, and possibly a name for each
328 * color
329 */
330
331 colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor));
332 if (!colorTable)
333 RETURN(XpmNoMemory);
334
335 /* compute the minimal cpp */
336 for (cppm = 1, c = MAXPRINTABLE; pmap.ncolors > c; cppm++)
337 c *= MAXPRINTABLE;
338 if (cpp < cppm)
339 cpp = cppm;
340
341 if (pmap.mask_pixel) {
342 ErrorStatus = ScanTransparentColor(colorTable, cpp, attributes);
343 if (ErrorStatus != XpmSuccess)
344 RETURN(ErrorStatus);
e6ed776f 345 }
cfbe03c9 346
e6ed776f
GRG
347 ErrorStatus = ScanOtherColors(display, colorTable, pmap.ncolors,
348 pmap.pixels, pmap.mask_pixel, cpp,
349 attributes);
cfbe03c9
JS
350 if (ErrorStatus != XpmSuccess)
351 RETURN(ErrorStatus);
352
353 /*
354 * store found informations in the XpmImage structure
355 */
356 xpmimage->width = width;
357 xpmimage->height = height;
358 xpmimage->cpp = cpp;
359 xpmimage->ncolors = pmap.ncolors;
360 xpmimage->colorTable = colorTable;
361 xpmimage->data = pmap.pixelindex;
362
363 XpmFree(pmap.pixels);
364 return (XpmSuccess);
e6ed776f
GRG
365
366/* exit point in case of error, free only locally allocated variables */
367error:
368 if (pmap.pixelindex)
369 XpmFree(pmap.pixelindex);
370 if (pmap.pixels)
371 XpmFree(pmap.pixels);
372 if (colorTable)
373 xpmFreeColorTable(colorTable, pmap.ncolors);
374
375 return (ErrorStatus);
cfbe03c9
JS
376}
377
ea258ad3
DW
378#ifdef __OS2__
379/* Visual Age cannot deal with old, non-ansi, code */
380static int ScanTransparentColor(XpmColor* color, unsigned int cpp, XpmAttributes* attributes)
381#else
cfbe03c9 382static int
e6ed776f
GRG
383ScanTransparentColor(color, cpp, attributes)
384 XpmColor *color;
385 unsigned int cpp;
386 XpmAttributes *attributes;
ea258ad3 387#endif
cfbe03c9
JS
388{
389 char *s;
390 unsigned int a, b, c;
391
392 /* first get a character string */
393 a = 0;
394 if (!(s = color->string = (char *) XpmMalloc(cpp + 1)))
395 return (XpmNoMemory);
396 *s++ = printable[c = a % MAXPRINTABLE];
397 for (b = 1; b < cpp; b++, s++)
398 *s = printable[c = ((a - c) / MAXPRINTABLE) % MAXPRINTABLE];
399 *s = '\0';
400
401 /* then retreive related info from the attributes if any */
e6ed776f 402 if (attributes && (attributes->valuemask & XpmColorTable
cfbe03c9 403/* 3.2 backward compatibility code */
e6ed776f 404 || attributes->valuemask & XpmInfos)
cfbe03c9 405/* end 3.2 bc */
e6ed776f 406 && attributes->mask_pixel != XpmUndefPixel) {
cfbe03c9
JS
407
408 unsigned int key;
409 char **defaults = (char **) color;
410 char **mask_defaults;
411
412/* 3.2 backward compatibility code */
e6ed776f 413 if (attributes->valuemask & XpmColorTable)
cfbe03c9
JS
414/* end 3.2 bc */
415 mask_defaults = (char **) (
416 attributes->colorTable + attributes->mask_pixel);
e6ed776f
GRG
417/* 3.2 backward compatibility code */
418 else
419 mask_defaults = (char **)
420 ((XpmColor **) attributes->colorTable)[attributes->mask_pixel];
421/* end 3.2 bc */
cfbe03c9
JS
422 for (key = 1; key <= NKEYS; key++) {
423 if (s = mask_defaults[key]) {
e6ed776f 424 defaults[key] = (char *) xpmstrdup(s);
cfbe03c9
JS
425 if (!defaults[key])
426 return (XpmNoMemory);
427 }
428 }
429 } else {
e6ed776f 430 color->c_color = (char *) xpmstrdup(TRANSPARENT_COLOR);
cfbe03c9
JS
431 if (!color->c_color)
432 return (XpmNoMemory);
433 }
434 return (XpmSuccess);
435}
436
ea258ad3
DW
437#ifdef __OS2__
438/* Visual Age cannot deal with old, non-ansi, code */
439static int ScanOtherColors(
440 Display* display
441, XpmColor* colors
442, int ncolors
443, Pixel* pixels
444, unsigned int mask
445, unsigned int cpp
446, XpmAttributes* attributes
447)
448#else
cfbe03c9 449static int
e6ed776f
GRG
450ScanOtherColors(display, colors, ncolors, pixels, mask, cpp, attributes)
451 Display *display;
452 XpmColor *colors;
453 int ncolors;
454 Pixel *pixels;
455 unsigned int mask;
456 unsigned int cpp;
457 XpmAttributes *attributes;
ea258ad3 458#endif
cfbe03c9
JS
459{
460 /* variables stored in the XpmAttributes structure */
461 Colormap colormap;
462 char *rgb_fname;
463
464#ifndef FOR_MSW
465 xpmRgbName rgbn[MAX_RGBNAMES];
466#else
ea258ad3
DW
467 xpmRgbName *rgbn = NULL;
468#endif
cfbe03c9
JS
469 int rgbn_max = 0;
470 unsigned int i, j, c, i2;
471 XpmColor *color;
472 XColor *xcolors = NULL, *xcolor;
473 char *colorname, *s;
474 XpmColor *colorTable, **oldColorTable = NULL;
475 unsigned int ancolors = 0;
476 Pixel *apixels;
477 unsigned int mask_pixel;
e6ed776f 478 Bool found;
cfbe03c9
JS
479
480 /* retrieve information from the XpmAttributes */
481 if (attributes && (attributes->valuemask & XpmColormap))
482 colormap = attributes->colormap;
483 else
484 colormap = XDefaultColormap(display, XDefaultScreen(display));
485 if (attributes && (attributes->valuemask & XpmRgbFilename))
486 rgb_fname = attributes->rgb_fname;
487 else
488 rgb_fname = NULL;
489
e6ed776f
GRG
490 /* start from the right element */
491 if (mask) {
492 colors++;
493 ncolors--;
494 pixels++;
495 }
496
cfbe03c9
JS
497 /* first get character strings and rgb values */
498 xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors);
499 if (!xcolors)
500 return (XpmNoMemory);
501
e6ed776f
GRG
502 for (i = 0, i2 = mask, color = colors, xcolor = xcolors;
503 i < ncolors; i++, i2++, color++, xcolor++, pixels++) {
cfbe03c9
JS
504
505 if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) {
506 XpmFree(xcolors);
507 return (XpmNoMemory);
508 }
509 *s++ = printable[c = i2 % MAXPRINTABLE];
510 for (j = 1; j < cpp; j++, s++)
511 *s = printable[c = ((i2 - c) / MAXPRINTABLE) % MAXPRINTABLE];
512 *s = '\0';
513
514 xcolor->pixel = *pixels;
515 }
ea258ad3
DW
516#ifdef __OS2__
517 XQueryColors(display, &colormap, xcolors, ncolors);
518#else
e6ed776f 519 XQueryColors(display, colormap, xcolors, ncolors);
ea258ad3 520#endif
cfbe03c9
JS
521
522#ifndef FOR_MSW
523 /* read the rgb file if any was specified */
524 if (rgb_fname)
525 rgbn_max = xpmReadRgbNames(attributes->rgb_fname, rgbn);
526#else
527 /* FOR_MSW: rgb names and values are hardcoded in rgbtab.h */
528 rgbn_max = xpmReadRgbNames(NULL, NULL);
529#endif
530
531 if (attributes && attributes->valuemask & XpmColorTable) {
532 colorTable = attributes->colorTable;
533 ancolors = attributes->ncolors;
534 apixels = attributes->pixels;
535 mask_pixel = attributes->mask_pixel;
536 }
537/* 3.2 backward compatibility code */
538 else if (attributes && attributes->valuemask & XpmInfos) {
539 oldColorTable = (XpmColor **) attributes->colorTable;
540 ancolors = attributes->ncolors;
541 apixels = attributes->pixels;
542 mask_pixel = attributes->mask_pixel;
543 }
544/* end 3.2 bc */
545
e6ed776f 546 for (i = 0, color = colors, xcolor = xcolors; i < ncolors;
cfbe03c9
JS
547 i++, color++, xcolor++) {
548
549 /* look for related info from the attributes if any */
550 found = False;
551 if (ancolors) {
552 unsigned int offset = 0;
553
554 for (j = 0; j < ancolors; j++) {
555 if (j == mask_pixel) {
556 offset = 1;
557 continue;
558 }
559 if (apixels[j - offset] == xcolor->pixel)
560 break;
561 }
562 if (j != ancolors) {
563 unsigned int key;
564 char **defaults = (char **) color;
565 char **adefaults;
566
567/* 3.2 backward compatibility code */
568 if (oldColorTable)
569 adefaults = (char **) oldColorTable[j];
570 else
571/* end 3.2 bc */
572 adefaults = (char **) (colorTable + j);
573
574 found = True;
575 for (key = 1; key <= NKEYS; key++) {
576 if (s = adefaults[key])
e6ed776f 577 defaults[key] = (char *) xpmstrdup(s);
cfbe03c9
JS
578 }
579 }
580 }
581 if (!found) {
582 /* if nothing found look for a color name */
583 colorname = NULL;
584 if (rgbn_max)
585 colorname = xpmGetRgbName(rgbn, rgbn_max, xcolor->red,
586 xcolor->green, xcolor->blue);
587 if (colorname)
e6ed776f 588 color->c_color = (char *) xpmstrdup(colorname);
cfbe03c9
JS
589 else {
590 /* at last store the rgb value */
591 char buf[BUFSIZ];
592#ifndef FOR_MSW
593 sprintf(buf, "#%04X%04X%04X",
594 xcolor->red, xcolor->green, xcolor->blue);
ea258ad3 595#else
cfbe03c9
JS
596 sprintf(buf, "#%02x%02x%02x",
597 xcolor->red, xcolor->green, xcolor->blue);
598#endif
e6ed776f 599 color->c_color = (char *) xpmstrdup(buf);
cfbe03c9
JS
600 }
601 if (!color->c_color) {
602 XpmFree(xcolors);
603 xpmFreeRgbNames(rgbn, rgbn_max);
604 return (XpmNoMemory);
605 }
606 }
607 }
608
609 XpmFree(xcolors);
610 xpmFreeRgbNames(rgbn, rgbn_max);
611 return (XpmSuccess);
612}
613
614#ifndef FOR_MSW
e6ed776f 615# ifndef AMIGA
cfbe03c9
JS
616/*
617 * The functions below are written from X11R5 MIT's code (XImUtil.c)
618 *
619 * The idea is to have faster functions than the standard XGetPixel function
620 * to scan the image data. Indeed we can speed up things by suppressing tests
621 * performed for each pixel. We do exactly the same tests but at the image
e6ed776f 622 * level.
cfbe03c9
JS
623 */
624
625static unsigned long Const low_bits_table[] = {
626 0x00000000, 0x00000001, 0x00000003, 0x00000007,
627 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
628 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
629 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
630 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
631 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
632 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
633 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
634 0xffffffff
635};
636
637/*
e6ed776f 638 * Default method to scan pixels of an image data structure.
cfbe03c9
JS
639 * The algorithm used is:
640 *
641 * copy the source bitmap_unit or Zpixel into temp
642 * normalize temp if needed
643 * extract the pixel bits into return value
644 *
645 */
646
ea258ad3
DW
647#ifdef __OS2__
648/* Visual Age cannot deal with old, non-ansi, code */
649static int GetImagePixels(
650 XImage* image
651, unsigned int width
652, unsigned int height
653, PixelsMap* pmap
654)
655#else
cfbe03c9 656static int
e6ed776f
GRG
657GetImagePixels(image, width, height, pmap)
658 XImage *image;
659 unsigned int width;
660 unsigned int height;
661 PixelsMap *pmap;
ea258ad3 662#endif
cfbe03c9
JS
663{
664 char *src;
665 char *dst;
666 unsigned int *iptr;
667 char *data;
668 int x, y, i;
e6ed776f 669 int bits, depth, ibu, ibpp, offset;
cfbe03c9
JS
670 unsigned long lbt;
671 Pixel pixel, px;
672
673 data = image->data;
674 iptr = pmap->pixelindex;
675 depth = image->depth;
676 lbt = low_bits_table[depth];
677 ibpp = image->bits_per_pixel;
e6ed776f
GRG
678 offset = image->xoffset;
679
680 if ((image->bits_per_pixel | image->depth) == 1) {
cfbe03c9
JS
681 ibu = image->bitmap_unit;
682 for (y = 0; y < height; y++)
683 for (x = 0; x < width; x++, iptr++) {
684 src = &data[XYINDEX(x, y, image)];
685 dst = (char *) &pixel;
686 pixel = 0;
687 for (i = ibu >> 3; --i >= 0;)
688 *dst++ = *src++;
689 XYNORMALIZE(&pixel, image);
e6ed776f 690 bits = (x + offset) % ibu;
cfbe03c9
JS
691 pixel = ((((char *) &pixel)[bits >> 3]) >> (bits & 7)) & 1;
692 if (ibpp != depth)
693 pixel &= lbt;
694 if (storePixel(pixel, pmap, iptr))
695 return (XpmNoMemory);
696 }
e6ed776f
GRG
697 } else if (image->format == XYPixmap) {
698 int nbytes, bpl, j;
699 long plane = 0;
700 ibu = image->bitmap_unit;
701 nbytes = ibu >> 3;
702 bpl = image->bytes_per_line;
703 for (y = 0; y < height; y++)
704 for (x = 0; x < width; x++, iptr++) {
705 pixel = 0;
706 plane = 0;
707 for (i = depth; --i >= 0;) {
708 src = &data[XYINDEX(x, y, image) + plane];
709 dst = (char *) &px;
710 px = 0;
711 for (j = nbytes; --j >= 0;)
712 *dst++ = *src++;
713 XYNORMALIZE(&px, image);
714 bits = (x + offset) % ibu;
715 pixel = (pixel << 1) |
716 (((((char *) &px)[bits >> 3]) >> (bits & 7)) & 1);
717 plane = plane + (bpl * height);
718 }
719 if (ibpp != depth)
720 pixel &= lbt;
721 if (storePixel(pixel, pmap, iptr))
722 return (XpmNoMemory);
723 }
724 } else if (image->format == ZPixmap) {
cfbe03c9
JS
725 for (y = 0; y < height; y++)
726 for (x = 0; x < width; x++, iptr++) {
727 src = &data[ZINDEX(x, y, image)];
728 dst = (char *) &px;
729 px = 0;
730 for (i = (ibpp + 7) >> 3; --i >= 0;)
731 *dst++ = *src++;
732 ZNORMALIZE(&px, image);
733 pixel = 0;
734 for (i = sizeof(unsigned long); --i >= 0;)
735 pixel = (pixel << 8) | ((unsigned char *) &px)[i];
736 if (ibpp == 4) {
737 if (x & 1)
738 pixel >>= 4;
739 else
740 pixel &= 0xf;
741 }
742 if (ibpp != depth)
743 pixel &= lbt;
744 if (storePixel(pixel, pmap, iptr))
745 return (XpmNoMemory);
746 }
e6ed776f
GRG
747 } else
748 return (XpmColorError); /* actually a bad image */
cfbe03c9
JS
749 return (XpmSuccess);
750}
751
752/*
753 * scan pixels of a 32-bits Z image data structure
754 */
755
e6ed776f 756#if !defined(WORD64) && !defined(LONG64)
cfbe03c9 757static unsigned long byteorderpixel = MSBFirst << 24;
cfbe03c9
JS
758#endif
759
ea258ad3
DW
760#ifdef __OS2__
761/* Visual Age cannot deal with old, non-ansi, code */
762static int GetImagePixels32(
763 XImage* image
764, unsigned int width
765, unsigned int height
766, PixelsMap* pmap
767)
768#else
cfbe03c9 769static int
e6ed776f
GRG
770GetImagePixels32(image, width, height, pmap)
771 XImage *image;
772 unsigned int width;
773 unsigned int height;
774 PixelsMap *pmap;
ea258ad3 775#endif
cfbe03c9
JS
776{
777 unsigned char *addr;
778 unsigned char *data;
779 unsigned int *iptr;
780 int x, y;
781 unsigned long lbt;
782 Pixel pixel;
783 int depth;
784
785 data = (unsigned char *) image->data;
786 iptr = pmap->pixelindex;
787 depth = image->depth;
788 lbt = low_bits_table[depth];
e6ed776f 789#if !defined(WORD64) && !defined(LONG64)
cfbe03c9
JS
790 if (*((char *) &byteorderpixel) == image->byte_order) {
791 for (y = 0; y < height; y++)
792 for (x = 0; x < width; x++, iptr++) {
793 addr = &data[ZINDEX32(x, y, image)];
794 pixel = *((unsigned long *) addr);
795 if (depth != 32)
796 pixel &= lbt;
797 if (storePixel(pixel, pmap, iptr))
798 return (XpmNoMemory);
799 }
800 } else
801#endif
802 if (image->byte_order == MSBFirst)
803 for (y = 0; y < height; y++)
804 for (x = 0; x < width; x++, iptr++) {
805 addr = &data[ZINDEX32(x, y, image)];
806 pixel = ((unsigned long) addr[0] << 24 |
807 (unsigned long) addr[1] << 16 |
808 (unsigned long) addr[2] << 8 |
e6ed776f 809 addr[3]);
cfbe03c9
JS
810 if (depth != 32)
811 pixel &= lbt;
812 if (storePixel(pixel, pmap, iptr))
813 return (XpmNoMemory);
814 }
815 else
816 for (y = 0; y < height; y++)
817 for (x = 0; x < width; x++, iptr++) {
818 addr = &data[ZINDEX32(x, y, image)];
819 pixel = (addr[0] |
820 (unsigned long) addr[1] << 8 |
821 (unsigned long) addr[2] << 16 |
822 (unsigned long) addr[3] << 24);
823 if (depth != 32)
824 pixel &= lbt;
825 if (storePixel(pixel, pmap, iptr))
826 return (XpmNoMemory);
827 }
828 return (XpmSuccess);
829}
830
831/*
832 * scan pixels of a 16-bits Z image data structure
833 */
834
ea258ad3
DW
835#ifdef __OS2__
836/* Visual Age cannot deal with old, non-ansi, code */
837static int GetImagePixels16(
838 XImage* image
839, unsigned int width
840, unsigned int height
841, PixelsMap* pmap
842)
843#else
cfbe03c9 844static int
e6ed776f
GRG
845GetImagePixels16(image, width, height, pmap)
846 XImage *image;
847 unsigned int width;
848 unsigned int height;
849 PixelsMap *pmap;
ea258ad3 850#endif
cfbe03c9
JS
851{
852 unsigned char *addr;
853 unsigned char *data;
854 unsigned int *iptr;
855 int x, y;
856 unsigned long lbt;
857 Pixel pixel;
858 int depth;
859
860 data = (unsigned char *) image->data;
861 iptr = pmap->pixelindex;
862 depth = image->depth;
863 lbt = low_bits_table[depth];
864 if (image->byte_order == MSBFirst)
865 for (y = 0; y < height; y++)
866 for (x = 0; x < width; x++, iptr++) {
867 addr = &data[ZINDEX16(x, y, image)];
868 pixel = addr[0] << 8 | addr[1];
869 if (depth != 16)
870 pixel &= lbt;
871 if (storePixel(pixel, pmap, iptr))
872 return (XpmNoMemory);
873 }
874 else
875 for (y = 0; y < height; y++)
876 for (x = 0; x < width; x++, iptr++) {
877 addr = &data[ZINDEX16(x, y, image)];
878 pixel = addr[0] | addr[1] << 8;
879 if (depth != 16)
880 pixel &= lbt;
881 if (storePixel(pixel, pmap, iptr))
882 return (XpmNoMemory);
883 }
884 return (XpmSuccess);
885}
886
887/*
888 * scan pixels of a 8-bits Z image data structure
889 */
890
ea258ad3
DW
891#ifdef __OS2__
892/* Visual Age cannot deal with old, non-ansi, code */
893static int
894GetImagePixels8(image, width, height, pmap)
895 XImage* image
896, unsigned int width
897, unsigned int height
898, PixelsMap* pmap
899)
900#else
cfbe03c9 901static int
e6ed776f
GRG
902GetImagePixels8(image, width, height, pmap)
903 XImage *image;
904 unsigned int width;
905 unsigned int height;
906 PixelsMap *pmap;
ea258ad3 907#endif
cfbe03c9
JS
908{
909 unsigned int *iptr;
910 unsigned char *data;
911 int x, y;
912 unsigned long lbt;
913 Pixel pixel;
914 int depth;
915
916 data = (unsigned char *) image->data;
917 iptr = pmap->pixelindex;
918 depth = image->depth;
919 lbt = low_bits_table[depth];
920 for (y = 0; y < height; y++)
921 for (x = 0; x < width; x++, iptr++) {
922 pixel = data[ZINDEX8(x, y, image)];
923 if (depth != 8)
924 pixel &= lbt;
925 if (storePixel(pixel, pmap, iptr))
926 return (XpmNoMemory);
927 }
928 return (XpmSuccess);
929}
930
931/*
932 * scan pixels of a 1-bit depth Z image data structure
933 */
934
ea258ad3
DW
935#ifdef __OS2__
936/* Visual Age cannot deal with old, non-ansi, code */
937static int
938GetImagePixels1(
939 XImage* image
940, unsigned int width
941, unsigned int height
942, PixelsMap* pmap
943, int (*storeFunc) ()
944)
945#else
cfbe03c9 946static int
e6ed776f
GRG
947GetImagePixels1(image, width, height, pmap, storeFunc)
948 XImage *image;
949 unsigned int width;
950 unsigned int height;
951 PixelsMap *pmap;
952 int (*storeFunc) ();
ea258ad3 953#endif
cfbe03c9
JS
954{
955 unsigned int *iptr;
956 int x, y;
957 char *data;
958 Pixel pixel;
e6ed776f 959 int xoff, yoff, offset, bpl;
cfbe03c9 960
e6ed776f
GRG
961 data = image->data;
962 iptr = pmap->pixelindex;
963 offset = image->xoffset;
964 bpl = image->bytes_per_line;
965
966 if (image->bitmap_bit_order == MSBFirst)
967 for (y = 0; y < height; y++)
968 for (x = 0; x < width; x++, iptr++) {
969 xoff = x + offset;
970 yoff = y * bpl + (xoff >> 3);
971 xoff &= 7;
972 pixel = (data[yoff] & (0x80 >> xoff)) ? 1 : 0;
973 if ((*storeFunc) (pixel, pmap, iptr))
974 return (XpmNoMemory);
975 }
976 else
977 for (y = 0; y < height; y++)
978 for (x = 0; x < width; x++, iptr++) {
979 xoff = x + offset;
980 yoff = y * bpl + (xoff >> 3);
981 xoff &= 7;
982 pixel = (data[yoff] & (1 << xoff)) ? 1 : 0;
983 if ((*storeFunc) (pixel, pmap, iptr))
984 return (XpmNoMemory);
985 }
cfbe03c9
JS
986 return (XpmSuccess);
987}
988
e6ed776f
GRG
989# else /* AMIGA */
990
991#define CLEAN_UP(status) \
992{\
993 if (pixels) XpmFree (pixels);\
994 if (tmp_img) FreeXImage (tmp_img);\
995 return (status);\
996}
997
998static int
999AGetImagePixels (
1000 XImage *image,
1001 unsigned int width,
1002 unsigned int height,
1003 PixelsMap *pmap,
1004 int (*storeFunc) ())
1005{
1006 unsigned int *iptr;
1007 unsigned int x, y;
1008 unsigned char *pixels;
1009 XImage *tmp_img;
ea258ad3 1010
e6ed776f
GRG
1011 pixels = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*pixels));
1012 if (pixels == NULL)
1013 return XpmNoMemory;
ea258ad3 1014
e6ed776f
GRG
1015 tmp_img = AllocXImage ((((width+15)>>4)<<4), 1, image->rp->BitMap->Depth);
1016 if (tmp_img == NULL)
1017 CLEAN_UP (XpmNoMemory)
ea258ad3 1018
e6ed776f
GRG
1019 iptr = pmap->pixelindex;
1020 for (y = 0; y < height; ++y)
1021 {
1022 ReadPixelLine8 (image->rp, 0, y, width, pixels, tmp_img->rp);
1023 for (x = 0; x < width; ++x, ++iptr)
1024 {
1025 if ((*storeFunc) (pixels[x], pmap, iptr))
1026 CLEAN_UP (XpmNoMemory)
1027 }
1028 }
ea258ad3 1029
e6ed776f
GRG
1030 CLEAN_UP (XpmSuccess)
1031}
1032
1033#undef CLEAN_UP
1034
1035# endif/* AMIGA */
cfbe03c9 1036#else /* ndef FOR_MSW */
ea258ad3
DW
1037#ifdef __OS2__
1038/* Visual Age cannot deal with old, non-ansi, code */
1039static int
1040MSWGetImagePixels(
1041 Display* display
1042, XImage* image
1043, unsigned int width
1044, unsigned int height
1045, PixelsMap* pmap
1046, int (*storeFunc) ()
1047)
1048#else
cfbe03c9 1049static int
e6ed776f
GRG
1050MSWGetImagePixels(display, image, width, height, pmap, storeFunc)
1051 Display *display;
1052 XImage *image;
1053 unsigned int width;
1054 unsigned int height;
1055 PixelsMap *pmap;
1056 int (*storeFunc) ();
ea258ad3 1057#endif
cfbe03c9
JS
1058{
1059 unsigned int *iptr;
1060 unsigned int x, y;
1061 Pixel pixel;
ea258ad3
DW
1062#ifdef __OS2__
1063 HAB hab;
1064 HPS hps;
1065 DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL};
1066 SIZEL sizl = {0, 0};
1067 POINTL point;
1068#endif
cfbe03c9
JS
1069
1070 iptr = pmap->pixelindex;
1071
ea258ad3
DW
1072#ifdef __OS2__
1073 hps = GpiCreatePS(hab, *display, &sizl, GPIA_ASSOC | PU_PELS);
1074 GpiSetBitmap(hps, image->bitmap);
1075#else
e6ed776f 1076 SelectObject(*display, image->bitmap);
ea258ad3
DW
1077#endif
1078
cfbe03c9
JS
1079 for (y = 0; y < height; y++) {
1080 for (x = 0; x < width; x++, iptr++) {
ea258ad3
DW
1081#ifdef __OS2__
1082 point.x = x;
1083 point.y = y;
1084 pixel = GpiQueryPel(hps, &point);
1085#else
cfbe03c9 1086 pixel = GetPixel(*display, x, y);
ea258ad3
DW
1087#endif
1088#ifndef __OS2__
1089/* calling convention all messed up under OS/2 */
e6ed776f 1090 if ((*storeFunc) (pixel, pmap, iptr))
cfbe03c9 1091 return (XpmNoMemory);
ea258ad3 1092#endif
cfbe03c9
JS
1093 }
1094 }
1095 return (XpmSuccess);
1096}
1097
1098#endif
1099
1100#ifndef FOR_MSW
e6ed776f 1101# ifndef AMIGA
cfbe03c9 1102int
e6ed776f
GRG
1103XpmCreateXpmImageFromPixmap(display, pixmap, shapemask,
1104 xpmimage, attributes)
1105 Display *display;
1106 Pixmap pixmap;
1107 Pixmap shapemask;
1108 XpmImage *xpmimage;
1109 XpmAttributes *attributes;
cfbe03c9
JS
1110{
1111 XImage *ximage = NULL;
1112 XImage *shapeimage = NULL;
1113 unsigned int width = 0;
1114 unsigned int height = 0;
1115 int ErrorStatus;
1116
1117 /* get geometry */
1118 if (attributes && attributes->valuemask & XpmSize) {
1119 width = attributes->width;
1120 height = attributes->height;
1121 }
1122 /* get the ximages */
1123 if (pixmap)
1124 xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height);
1125 if (shapemask)
1126 xpmCreateImageFromPixmap(display, shapemask, &shapeimage,
1127 &width, &height);
1128
1129 /* create the related XpmImage */
1130 ErrorStatus = XpmCreateXpmImageFromImage(display, ximage, shapeimage,
1131 xpmimage, attributes);
1132
1133 /* destroy the ximages */
1134 if (ximage)
1135 XDestroyImage(ximage);
1136 if (shapeimage)
1137 XDestroyImage(shapeimage);
1138
1139 return (ErrorStatus);
1140}
1141
e6ed776f 1142# endif/* not AMIGA */
cfbe03c9 1143#endif /* ndef FOR_MSW */