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