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