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