]>
git.saurik.com Git - wxWidgets.git/blob - src/mac/xpm/scan.c
2 * Copyright (C) 1989-95 GROUPE BULL
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
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.
26 /*****************************************************************************\
30 * Scanning utility for XPM file format *
32 * Developed by Arnaud Le Hors *
33 \*****************************************************************************/
36 * The code related to FOR_MSW has been added by
37 * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
41 * The code related to AMIGA has been added by
42 * Lorens Younes (d93-hyo@nada.kth.se) 4/96
47 #define MAXPRINTABLE 92 /* number of printable ascii chars
48 * minus \ and " for string compat
49 * and ? to avoid ANSI trigraphs. */
51 static char *printable
=
52 " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\
53 ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
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
64 unsigned int *pixelindex
;
67 unsigned int mask_pixel
; /* whether there is or not */
70 LFUNC(storePixel
, int, (Pixel pixel
, PixelsMap
*pmap
,
71 unsigned int *index_return
));
73 LFUNC(storeMaskPixel
, int, (Pixel pixel
, PixelsMap
*pmap
,
74 unsigned int *index_return
));
76 LFUNC(PlatformGetImagePixels
, int, (Display
*d
, XImage
*image
, unsigned int width
,
77 unsigned int height
, PixelsMap
*pmap
,
78 int (*storeFunc
) ()));
79 LFUNC(ScanTransparentColor
, int, (XpmColor
*color
, unsigned int cpp
,
80 XpmAttributes
*attributes
));
82 LFUNC(ScanOtherColors
, int, (Display
*display
, XpmColor
*colors
, int ncolors
,
83 Pixel
*pixels
, unsigned int mask
,
84 unsigned int cpp
, XpmAttributes
*attributes
));
87 * This function stores the given pixel in the given arrays which are grown
88 * if not large enough.
91 storePixel(pixel
, pmap
, index_return
)
94 unsigned int *index_return
;
100 if (*index_return
) { /* this is a transparent pixel! */
104 ncolors
= pmap
->ncolors
;
105 p
= pmap
->pixels
+ pmap
->mask_pixel
;
106 for (i
= pmap
->mask_pixel
; i
< ncolors
; i
++, p
++)
107 if ( IS_EQUAL_PIXEL(*p
, pixel
) )
110 if (ncolors
>= pmap
->size
) {
112 p
= (Pixel
*) XpmRealloc(pmap
->pixels
, sizeof(Pixel
) * pmap
->size
);
118 (pmap
->pixels
)[ncolors
] = pixel
;
126 storeMaskPixel(pixel
, pmap
, index_return
)
129 unsigned int *index_return
;
131 if (IS_ZERO_PIXEL(pixel
)) {
132 if (!pmap
->ncolors
) {
134 SET_ZERO_PIXEL((pmap
->pixels
)[0]);
135 pmap
->mask_pixel
= 1;
143 /* function call in case of error */
145 #define RETURN(status) \
147 ErrorStatus = status; \
152 * This function scans the given image and stores the found informations in
153 * the given XpmImage structure.
156 XpmCreateXpmImageFromImage(display
, image
, shapeimage
,
157 xpmimage
, attributes
)
162 XpmAttributes
*attributes
;
164 /* variables stored in the XpmAttributes structure */
167 /* variables to return */
169 XpmColor
*colorTable
= NULL
;
172 /* calculation variables */
173 unsigned int width
= 0;
174 unsigned int height
= 0;
175 unsigned int cppm
; /* minimum chars per pixel */
178 /* initialize pmap */
180 pmap
.pixelindex
= NULL
;
181 pmap
.size
= 256; /* should be enough most of the time */
189 width
= image
->width
;
190 height
= image
->height
;
191 } else if (shapeimage
) {
192 width
= shapeimage
->width
;
193 height
= shapeimage
->height
;
197 * retrieve information from the XpmAttributes
199 if (attributes
&& (attributes
->valuemask
& XpmCharsPerPixel
200 /* 3.2 backward compatibility code */
201 || attributes
->valuemask
& XpmInfos
))
203 cpp
= attributes
->cpp
;
208 (unsigned int *) XpmCalloc(width
* height
, sizeof(unsigned int));
209 if (!pmap
.pixelindex
)
212 pmap
.pixels
= (Pixel
*) XpmMalloc(sizeof(Pixel
) * pmap
.size
);
217 * scan shape mask if any
221 ErrorStatus
= PlatformGetImagePixels(display
, shapeimage
, width
, height
,
222 &pmap
, storeMaskPixel
);
224 if (ErrorStatus
!= XpmSuccess
)
229 * scan the image data
231 * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use optimized
232 * functions, otherwise use slower but sure general one.
238 ErrorStatus
= PlatformGetImagePixels(display
, image
, width
, height
, &pmap
,
241 if (ErrorStatus
!= XpmSuccess
)
246 * get rgb values and a string of char, and possibly a name for each
250 colorTable
= (XpmColor
*) XpmCalloc(pmap
.ncolors
, sizeof(XpmColor
));
254 /* compute the minimal cpp */
255 for (cppm
= 1, c
= MAXPRINTABLE
; pmap
.ncolors
> c
; cppm
++)
260 if (pmap
.mask_pixel
) {
261 ErrorStatus
= ScanTransparentColor(colorTable
, cpp
, attributes
);
262 if (ErrorStatus
!= XpmSuccess
)
266 ErrorStatus
= ScanOtherColors(display
, colorTable
, pmap
.ncolors
,
267 pmap
.pixels
, pmap
.mask_pixel
, cpp
,
269 if (ErrorStatus
!= XpmSuccess
)
273 * store found informations in the XpmImage structure
275 xpmimage
->width
= width
;
276 xpmimage
->height
= height
;
278 xpmimage
->ncolors
= pmap
.ncolors
;
279 xpmimage
->colorTable
= colorTable
;
280 xpmimage
->data
= pmap
.pixelindex
;
282 XpmFree(pmap
.pixels
);
285 /* exit point in case of error, free only locally allocated variables */
288 XpmFree(pmap
.pixelindex
);
290 XpmFree(pmap
.pixels
);
292 xpmFreeColorTable(colorTable
, pmap
.ncolors
);
294 return (ErrorStatus
);
298 ScanTransparentColor(color
, cpp
, attributes
)
301 XpmAttributes
*attributes
;
304 unsigned int a
, b
, c
;
306 /* first get a character string */
308 if (!(s
= color
->string
= (char *) XpmMalloc(cpp
+ 1)))
309 return (XpmNoMemory
);
310 *s
++ = printable
[c
= a
% MAXPRINTABLE
];
311 for (b
= 1; b
< cpp
; b
++, s
++)
312 *s
= printable
[c
= ((a
- c
) / MAXPRINTABLE
) % MAXPRINTABLE
];
315 /* then retreive related info from the attributes if any */
316 if (attributes
&& (attributes
->valuemask
& XpmColorTable
317 /* 3.2 backward compatibility code */
318 || attributes
->valuemask
& XpmInfos
)
320 && attributes
->mask_pixel
!= XpmUndefPixel
) {
323 char **defaults
= (char **) color
;
324 char **mask_defaults
;
326 /* 3.2 backward compatibility code */
327 if (attributes
->valuemask
& XpmColorTable
)
329 mask_defaults
= (char **) (
330 attributes
->colorTable
+ attributes
->mask_pixel
);
331 /* 3.2 backward compatibility code */
333 mask_defaults
= (char **)
334 ((XpmColor
**) attributes
->colorTable
)[attributes
->mask_pixel
];
336 for (key
= 1; key
<= NKEYS
; key
++) {
337 if (s
= mask_defaults
[key
]) {
338 defaults
[key
] = (char *) xpmstrdup(s
);
340 return (XpmNoMemory
);
344 color
->c_color
= (char *) xpmstrdup(TRANSPARENT_COLOR
);
346 return (XpmNoMemory
);
352 ScanOtherColors(display
, colors
, ncolors
, pixels
, mask
, cpp
, attributes
)
359 XpmAttributes
*attributes
;
361 /* variables stored in the XpmAttributes structure */
365 xpmRgbName
*rgbn
= NULL
;
368 unsigned int i
, j
, c
, i2
;
370 XColor
*xcolors
= NULL
, *xcolor
;
372 XpmColor
*colorTable
, **oldColorTable
= NULL
;
373 unsigned int ancolors
= 0;
375 unsigned int mask_pixel
;
378 /* retrieve information from the XpmAttributes */
379 if (attributes
&& (attributes
->valuemask
& XpmColormap
))
380 colormap
= attributes
->colormap
;
382 colormap
= XDefaultColormap(display
, XDefaultScreen(display
));
383 if (attributes
&& (attributes
->valuemask
& XpmRgbFilename
))
384 rgb_fname
= attributes
->rgb_fname
;
388 /* start from the right element */
395 /* first get character strings and rgb values */
396 xcolors
= (XColor
*) XpmMalloc(sizeof(XColor
) * ncolors
);
398 return (XpmNoMemory
);
400 for (i
= 0, i2
= mask
, color
= colors
, xcolor
= xcolors
;
401 i
< ncolors
; i
++, i2
++, color
++, xcolor
++, pixels
++) {
403 if (!(s
= color
->string
= (char *) XpmMalloc(cpp
+ 1))) {
405 return (XpmNoMemory
);
407 *s
++ = printable
[c
= i2
% MAXPRINTABLE
];
408 for (j
= 1; j
< cpp
; j
++, s
++)
409 *s
= printable
[c
= ((i2
- c
) / MAXPRINTABLE
) % MAXPRINTABLE
];
412 xcolor
->pixel
= *pixels
;
414 XQueryColors(display
, colormap
, xcolors
, ncolors
);
416 rgbn_max
= xpmReadRgbNames(NULL
, NULL
);
418 if (attributes
&& attributes
->valuemask
& XpmColorTable
) {
419 colorTable
= attributes
->colorTable
;
420 ancolors
= attributes
->ncolors
;
421 apixels
= attributes
->pixels
;
422 mask_pixel
= attributes
->mask_pixel
;
424 /* 3.2 backward compatibility code */
425 else if (attributes
&& attributes
->valuemask
& XpmInfos
) {
426 oldColorTable
= (XpmColor
**) attributes
->colorTable
;
427 ancolors
= attributes
->ncolors
;
428 apixels
= attributes
->pixels
;
429 mask_pixel
= attributes
->mask_pixel
;
433 for (i
= 0, color
= colors
, xcolor
= xcolors
; i
< ncolors
;
434 i
++, color
++, xcolor
++) {
436 /* look for related info from the attributes if any */
439 unsigned int offset
= 0;
441 for (j
= 0; j
< ancolors
; j
++) {
442 if (j
== mask_pixel
) {
446 if (IS_EQUAL_PIXEL( apixels
[j
- offset
] , xcolor
->pixel
) )
451 char **defaults
= (char **) color
;
454 /* 3.2 backward compatibility code */
456 adefaults
= (char **) oldColorTable
[j
];
459 adefaults
= (char **) (colorTable
+ j
);
462 for (key
= 1; key
<= NKEYS
; key
++) {
463 if (s
= adefaults
[key
])
464 defaults
[key
] = (char *) xpmstrdup(s
);
469 /* if nothing found look for a color name */
472 colorname
= xpmGetRgbName(rgbn
, rgbn_max
, xcolor
->red
,
473 xcolor
->green
, xcolor
->blue
);
475 color
->c_color
= (char *) xpmstrdup(colorname
);
477 /* at last store the rgb value */
479 // sprintf(buf, "#%04X%04X%04X",
480 sprintf(buf
, "#%02x%02x%02x",
481 xcolor
->red
, xcolor
->green
, xcolor
->blue
);
483 color
->c_color
= (char *) xpmstrdup(buf
);
485 if (!color
->c_color
) {
487 xpmFreeRgbNames(rgbn
, rgbn_max
);
488 return (XpmNoMemory
);
494 xpmFreeRgbNames(rgbn
, rgbn_max
);
500 PlatformGetImagePixels(display
, image
, width
, height
, pmap
, storeFunc
)
513 iptr
= pmap
->pixelindex
;
515 SelectObject(*display
, image
->bitmap
);
516 for (y
= 0; y
< height
; y
++) {
517 for (x
= 0; x
< width
; x
++, iptr
++) {
518 pixel
= GetPixel(*display
, x
, y
);
519 if ((*storeFunc
) (pixel
, pmap
, iptr
))
520 return (XpmNoMemory
);