]>
Commit | Line | Data |
---|---|---|
0240e8b1 SC |
1 | /* |
2 | * Copyright (C) 1989-95 GROUPE BULL | |
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 | * create.c: * | |
28 | * * | |
29 | * XPM library * | |
30 | * Create an X image and possibly its related shape mask * | |
31 | * from the given XpmImage. * | |
32 | * * | |
33 | * Developed by Arnaud Le Hors * | |
34 | \*****************************************************************************/ | |
35 | ||
36 | /* | |
37 | * The code related to FOR_MSW has been added by | |
38 | * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 | |
39 | */ | |
40 | ||
41 | /* | |
42 | * The code related to AMIGA has been added by | |
43 | * Lorens Younes (d93-hyo@nada.kth.se) 4/96 | |
44 | */ | |
45 | ||
46 | #include "xpmi.h" | |
47 | #include <ctype.h> | |
48 | ||
49 | LFUNC(xpmVisualType, int, (Visual *visual)); | |
50 | ||
51 | LFUNC(AllocColor, int, (Display *display, Colormap colormap, | |
52 | char *colorname, XColor *xcolor, void *closure)); | |
53 | LFUNC(FreeColors, int, (Display *display, Colormap colormap, | |
54 | Pixel *pixels, int n, void *closure)); | |
55 | ||
56 | LFUNC(SetColor, int, (Display *display, Colormap colormap, Visual *visual, | |
57 | char *colorname, unsigned int color_index, | |
58 | Pixel *image_pixel, Pixel *mask_pixel, | |
59 | unsigned int *mask_pixel_index, | |
60 | Pixel *alloc_pixels, unsigned int *nalloc_pixels, | |
61 | Pixel *used_pixels, unsigned int *nused_pixels, | |
62 | XpmAttributes *attributes, XColor *cols, int ncols, | |
63 | XpmAllocColorFunc allocColor, void *closure)); | |
64 | ||
65 | LFUNC(CreateXImage, int, (Display *display, Visual *visual, | |
66 | unsigned int depth, int format, unsigned int width, | |
67 | unsigned int height, XImage **image_return)); | |
68 | ||
69 | LFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes, | |
70 | XpmColor *colors, unsigned int ncolors, | |
71 | Pixel *image_pixels, Pixel *mask_pixels, | |
72 | unsigned int *mask_pixel_index, | |
73 | Pixel *alloc_pixels, unsigned int *nalloc_pixels, | |
74 | Pixel *used_pixels, unsigned int *nused_pixels)); | |
75 | ||
76 | LFUNC(ParseAndPutPixels, int, (Display *dc, xpmData *data, unsigned int width, | |
77 | unsigned int height, unsigned int ncolors, | |
78 | unsigned int cpp, XpmColor *colorTable, | |
79 | xpmHashTable *hashtable, | |
80 | XImage *image, Pixel *image_pixels, | |
81 | XImage *mask, Pixel *mask_pixels)); | |
82 | ||
83 | LFUNC(PlatformPutImagePixels, void, (Display *dc, XImage *image, | |
84 | unsigned int width, unsigned int height, | |
85 | unsigned int *pixelindex, Pixel *pixels)); | |
86 | ||
87 | ||
88 | #ifdef NEED_STRCASECMP | |
89 | FUNC(xpmstrcasecmp, int, (char *s1, char *s2)); | |
90 | ||
91 | /* | |
92 | * in case strcasecmp is not provided by the system here is one | |
93 | * which does the trick | |
94 | */ | |
95 | int | |
96 | xpmstrcasecmp(s1, s2) | |
97 | register char *s1, *s2; | |
98 | { | |
99 | register int c1, c2; | |
100 | ||
101 | while (*s1 && *s2) { | |
102 | c1 = tolower(*s1); | |
103 | c2 = tolower(*s2); | |
104 | if (c1 != c2) | |
105 | return (c1 - c2); | |
106 | s1++; | |
107 | s2++; | |
108 | } | |
109 | return (int) (*s1 - *s2); | |
110 | } | |
111 | ||
112 | #endif | |
113 | ||
114 | /* | |
115 | * return the default color key related to the given visual | |
116 | */ | |
117 | static int | |
118 | xpmVisualType(visual) | |
119 | Visual *visual; | |
120 | { | |
121 | return (XPM_COLOR); | |
122 | } | |
123 | ||
124 | ||
125 | typedef struct { | |
126 | int cols_index; | |
127 | long closeness; | |
128 | } CloseColor; | |
129 | ||
130 | static int | |
131 | closeness_cmp(a, b) | |
132 | Const void *a, *b; | |
133 | { | |
134 | CloseColor *x = (CloseColor *) a, *y = (CloseColor *) b; | |
135 | ||
136 | /* cast to int as qsort requires */ | |
137 | return (int) (x->closeness - y->closeness); | |
138 | } | |
139 | ||
140 | ||
141 | /* default AllocColor function: | |
142 | * call XParseColor if colorname is given, return negative value if failure | |
143 | * call XAllocColor and return 0 if failure, positive otherwise | |
144 | */ | |
145 | static int | |
146 | AllocColor(display, colormap, colorname, xcolor, closure) | |
147 | Display *display; | |
148 | Colormap colormap; | |
149 | char *colorname; | |
150 | XColor *xcolor; | |
151 | void *closure; /* not used */ | |
152 | { | |
153 | int status; | |
154 | if (colorname) | |
155 | if (!XParseColor(display, colormap, colorname, xcolor)) | |
156 | return -1; | |
157 | status = XAllocColor(display, colormap, xcolor); | |
158 | return status != 0 ? 1 : 0; | |
159 | } | |
160 | ||
161 | /* | |
162 | * set the color pixel related to the given colorname, | |
163 | * return 0 if success, 1 otherwise. | |
164 | */ | |
165 | ||
166 | static int | |
167 | SetColor(display, colormap, visual, colorname, color_index, | |
168 | image_pixel, mask_pixel, mask_pixel_index, | |
169 | alloc_pixels, nalloc_pixels, used_pixels, nused_pixels, | |
170 | attributes, cols, ncols, allocColor, closure) | |
171 | Display *display; | |
172 | Colormap colormap; | |
173 | Visual *visual; | |
174 | char *colorname; | |
175 | unsigned int color_index; | |
176 | Pixel *image_pixel, *mask_pixel; | |
177 | unsigned int *mask_pixel_index; | |
178 | Pixel *alloc_pixels; | |
179 | unsigned int *nalloc_pixels; | |
180 | Pixel *used_pixels; | |
181 | unsigned int *nused_pixels; | |
182 | XpmAttributes *attributes; | |
183 | XColor *cols; | |
184 | int ncols; | |
185 | XpmAllocColorFunc allocColor; | |
186 | void *closure; | |
187 | { | |
188 | XColor xcolor; | |
189 | int status; | |
190 | ||
191 | if (xpmstrcasecmp(colorname, TRANSPARENT_COLOR)) | |
192 | { | |
193 | status = (*allocColor)(display, colormap, colorname, &xcolor, closure); | |
194 | if (status < 0) /* parse color failed */ | |
195 | return (1); | |
196 | ||
197 | if (status == 0) { | |
198 | return (1); | |
199 | } else | |
200 | alloc_pixels[(*nalloc_pixels)++] = xcolor.pixel; | |
201 | *image_pixel = xcolor.pixel; | |
202 | ||
203 | SET_ZERO_PIXEL( *mask_pixel ); | |
204 | ||
205 | used_pixels[(*nused_pixels)++] = xcolor.pixel; | |
206 | } | |
207 | else | |
208 | { | |
209 | // this is a special for mac - we have to get white as background for transparency | |
210 | #ifdef macintosh | |
211 | SET_WHITE_PIXEL( *image_pixel) ; | |
212 | #else | |
213 | SET_ZERO_PIXEL( *image_pixel); | |
214 | #endif | |
215 | SET_WHITE_PIXEL( *mask_pixel) ; | |
216 | ||
217 | /* store the color table index */ | |
218 | *mask_pixel_index = color_index; | |
219 | } | |
220 | return (0); | |
221 | } | |
222 | ||
223 | ||
224 | static int | |
225 | CreateColors(display, attributes, colors, ncolors, image_pixels, mask_pixels, | |
226 | mask_pixel_index, alloc_pixels, nalloc_pixels, | |
227 | used_pixels, nused_pixels) | |
228 | Display *display; | |
229 | XpmAttributes *attributes; | |
230 | XpmColor *colors; | |
231 | unsigned int ncolors; | |
232 | Pixel *image_pixels; | |
233 | Pixel *mask_pixels; | |
234 | unsigned int *mask_pixel_index; | |
235 | Pixel *alloc_pixels; | |
236 | unsigned int *nalloc_pixels; | |
237 | Pixel *used_pixels; | |
238 | unsigned int *nused_pixels; | |
239 | { | |
240 | /* variables stored in the XpmAttributes structure */ | |
241 | Visual *visual; | |
242 | Colormap colormap; | |
243 | XpmColorSymbol *colorsymbols; | |
244 | unsigned int numsymbols; | |
245 | XpmAllocColorFunc allocColor; | |
246 | void *closure; | |
247 | ||
248 | char *colorname; | |
249 | unsigned int color, key; | |
250 | Bool pixel_defined; | |
251 | XpmColorSymbol *symbol; | |
252 | char **defaults; | |
253 | int ErrorStatus = XpmSuccess; | |
254 | char *s; | |
255 | int default_index; | |
256 | ||
257 | XColor *cols = NULL; | |
258 | unsigned int ncols = 0; | |
259 | ||
260 | /* | |
261 | * retrieve information from the XpmAttributes | |
262 | */ | |
263 | if (attributes && attributes->valuemask & XpmColorSymbols) { | |
264 | colorsymbols = attributes->colorsymbols; | |
265 | numsymbols = attributes->numsymbols; | |
266 | } else | |
267 | numsymbols = 0; | |
268 | ||
269 | if (attributes && attributes->valuemask & XpmVisual) | |
270 | visual = attributes->visual; | |
271 | else | |
272 | visual = XDefaultVisual(display, XDefaultScreen(display)); | |
273 | ||
274 | if (attributes && (attributes->valuemask & XpmColormap)) | |
275 | colormap = attributes->colormap; | |
276 | else | |
277 | colormap = XDefaultColormap(display, XDefaultScreen(display)); | |
278 | ||
279 | if (attributes && (attributes->valuemask & XpmColorKey)) | |
280 | key = attributes->color_key; | |
281 | else | |
282 | key = xpmVisualType(visual); | |
283 | ||
284 | if (attributes && (attributes->valuemask & XpmAllocColor)) | |
285 | allocColor = attributes->alloc_color; | |
286 | else | |
287 | allocColor = AllocColor; | |
288 | if (attributes && (attributes->valuemask & XpmColorClosure)) | |
289 | closure = attributes->color_closure; | |
290 | else | |
291 | closure = NULL; | |
292 | ||
293 | switch (key) { | |
294 | case XPM_MONO: | |
295 | default_index = 2; | |
296 | break; | |
297 | case XPM_GRAY4: | |
298 | default_index = 3; | |
299 | break; | |
300 | case XPM_GRAY: | |
301 | default_index = 4; | |
302 | break; | |
303 | case XPM_COLOR: | |
304 | default: | |
305 | default_index = 5; | |
306 | break; | |
307 | } | |
308 | ||
309 | for (color = 0; color < ncolors; color++, colors++, | |
310 | image_pixels++, mask_pixels++) { | |
311 | colorname = NULL; | |
312 | pixel_defined = False; | |
313 | defaults = (char **) colors; | |
314 | ||
315 | /* | |
316 | * look for a defined symbol | |
317 | */ | |
318 | if (numsymbols) { | |
319 | ||
320 | unsigned int n; | |
321 | ||
322 | s = defaults[1]; | |
323 | for (n = 0, symbol = colorsymbols; n < numsymbols; n++, symbol++) { | |
324 | if (symbol->name && s && !strcmp(symbol->name, s)) | |
325 | /* override name */ | |
326 | break; | |
327 | if (!symbol->name && symbol->value) { /* override value */ | |
328 | int def_index = default_index; | |
329 | ||
330 | while (defaults[def_index] == NULL) /* find defined | |
331 | * colorname */ | |
332 | --def_index; | |
333 | if (def_index < 2) {/* nothing towards mono, so try | |
334 | * towards color */ | |
335 | def_index = default_index + 1; | |
336 | while (def_index <= 5 && defaults[def_index] == NULL) | |
337 | ++def_index; | |
338 | } | |
339 | if (def_index >= 2 && defaults[def_index] != NULL && | |
340 | !xpmstrcasecmp(symbol->value, defaults[def_index])) | |
341 | break; | |
342 | } | |
343 | } | |
344 | if (n != numsymbols) { | |
345 | if (symbol->name && symbol->value) | |
346 | colorname = symbol->value; | |
347 | else | |
348 | pixel_defined = True; | |
349 | } | |
350 | } | |
351 | if (!pixel_defined) { /* pixel not given as symbol value */ | |
352 | ||
353 | unsigned int k; | |
354 | ||
355 | if (colorname) { /* colorname given as symbol value */ | |
356 | if (!SetColor(display, colormap, visual, colorname, color, | |
357 | image_pixels, mask_pixels, mask_pixel_index, | |
358 | alloc_pixels, nalloc_pixels, used_pixels, | |
359 | nused_pixels, attributes, cols, ncols, | |
360 | allocColor, closure)) | |
361 | pixel_defined = True; | |
362 | else | |
363 | ErrorStatus = XpmColorError; | |
364 | } | |
365 | k = key; | |
366 | while (!pixel_defined && k > 1) { | |
367 | if (defaults[k]) { | |
368 | if (!SetColor(display, colormap, visual, defaults[k], | |
369 | color, image_pixels, mask_pixels, | |
370 | mask_pixel_index, alloc_pixels, | |
371 | nalloc_pixels, used_pixels, nused_pixels, | |
372 | attributes, cols, ncols, | |
373 | allocColor, closure)) { | |
374 | pixel_defined = True; | |
375 | break; | |
376 | } else | |
377 | ErrorStatus = XpmColorError; | |
378 | } | |
379 | k--; | |
380 | } | |
381 | k = key + 1; | |
382 | while (!pixel_defined && k < NKEYS + 1) { | |
383 | if (defaults[k]) { | |
384 | if (!SetColor(display, colormap, visual, defaults[k], | |
385 | color, image_pixels, mask_pixels, | |
386 | mask_pixel_index, alloc_pixels, | |
387 | nalloc_pixels, used_pixels, nused_pixels, | |
388 | attributes, cols, ncols, | |
389 | allocColor, closure)) { | |
390 | pixel_defined = True; | |
391 | break; | |
392 | } else | |
393 | ErrorStatus = XpmColorError; | |
394 | } | |
395 | k++; | |
396 | } | |
397 | if (!pixel_defined) { | |
398 | if (cols) | |
399 | XpmFree(cols); | |
400 | return (XpmColorFailed); | |
401 | } | |
402 | } else { | |
403 | /* simply use the given pixel */ | |
404 | *image_pixels = symbol->pixel; | |
405 | /* the following makes the mask to be built even if none | |
406 | is given a particular pixel */ | |
407 | if (symbol->value | |
408 | && !xpmstrcasecmp(symbol->value, TRANSPARENT_COLOR)) | |
409 | { | |
410 | SET_ZERO_PIXEL( *mask_pixels ) ; | |
411 | *mask_pixel_index = color; | |
412 | } | |
413 | else | |
414 | { | |
415 | #ifdef macintosh | |
416 | SET_WHITE_PIXEL( *mask_pixels ) ; // is this correct CS ???? | |
417 | #else | |
418 | *mask_pixels = 1; // is this correct CS ???? | |
419 | #endif | |
420 | } | |
421 | used_pixels[(*nused_pixels)++] = *image_pixels; | |
422 | } | |
423 | } | |
424 | if (cols) | |
425 | XpmFree(cols); | |
426 | return (ErrorStatus); | |
427 | } | |
428 | ||
429 | ||
430 | /* default FreeColors function, simply call XFreeColors */ | |
431 | static int | |
432 | FreeColors(display, colormap, pixels, n, closure) | |
433 | Display *display; | |
434 | Colormap colormap; | |
435 | Pixel *pixels; | |
436 | int n; | |
437 | void *closure; /* not used */ | |
438 | { | |
439 | return XFreeColors(display, colormap, pixels, n, 0); | |
440 | } | |
441 | ||
442 | ||
443 | /* function call in case of error */ | |
444 | #undef RETURN | |
445 | #define RETURN(status) \ | |
446 | { \ | |
447 | ErrorStatus = status; \ | |
448 | goto error; \ | |
449 | } | |
450 | ||
451 | int | |
452 | XpmCreateImageFromXpmImage(display, image, | |
453 | image_return, shapeimage_return, attributes) | |
454 | Display *display; | |
455 | XpmImage *image; | |
456 | XImage **image_return; | |
457 | XImage **shapeimage_return; | |
458 | XpmAttributes *attributes; | |
459 | { | |
460 | /* variables stored in the XpmAttributes structure */ | |
461 | Visual *visual; | |
462 | Colormap colormap; | |
463 | unsigned int depth; | |
464 | int bitmap_format; | |
465 | XpmFreeColorsFunc freeColors; | |
466 | void *closure; | |
467 | ||
468 | /* variables to return */ | |
469 | XImage *ximage = NULL; | |
470 | XImage *shapeimage = NULL; | |
471 | unsigned int mask_pixel_index = XpmUndefPixel; | |
472 | int ErrorStatus; | |
473 | ||
474 | /* calculation variables */ | |
475 | Pixel *image_pixels = NULL; | |
476 | Pixel *mask_pixels = NULL; | |
477 | Pixel *alloc_pixels = NULL; | |
478 | Pixel *used_pixels = NULL; | |
479 | unsigned int nalloc_pixels = 0; | |
480 | unsigned int nused_pixels = 0; | |
481 | ||
482 | /* initialize return values */ | |
483 | if (image_return) | |
484 | *image_return = NULL; | |
485 | if (shapeimage_return) | |
486 | *shapeimage_return = NULL; | |
487 | ||
488 | /* retrieve information from the XpmAttributes */ | |
489 | if (attributes && (attributes->valuemask & XpmVisual)) | |
490 | visual = attributes->visual; | |
491 | else | |
492 | visual = XDefaultVisual(display, XDefaultScreen(display)); | |
493 | ||
494 | if (attributes && (attributes->valuemask & XpmColormap)) | |
495 | colormap = attributes->colormap; | |
496 | else | |
497 | colormap = XDefaultColormap(display, XDefaultScreen(display)); | |
498 | ||
499 | if (attributes && (attributes->valuemask & XpmDepth)) | |
500 | depth = attributes->depth; | |
501 | else | |
502 | depth = XDefaultDepth(display, XDefaultScreen(display)); | |
503 | ||
504 | if (attributes && (attributes->valuemask & XpmBitmapFormat)) | |
505 | bitmap_format = attributes->bitmap_format; | |
506 | else | |
507 | bitmap_format = ZPixmap; | |
508 | ||
509 | if (attributes && (attributes->valuemask & XpmFreeColors)) | |
510 | freeColors = attributes->free_colors; | |
511 | else | |
512 | freeColors = FreeColors; | |
513 | if (attributes && (attributes->valuemask & XpmColorClosure)) | |
514 | closure = attributes->color_closure; | |
515 | else | |
516 | closure = NULL; | |
517 | ||
518 | ErrorStatus = XpmSuccess; | |
519 | ||
520 | /* malloc pixels index tables */ | |
521 | image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); | |
522 | if (!image_pixels) | |
523 | return (XpmNoMemory); | |
524 | ||
525 | mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); | |
526 | if (!mask_pixels) | |
527 | RETURN(XpmNoMemory); | |
528 | ||
529 | /* maximum of allocated pixels will be the number of colors */ | |
530 | alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); | |
531 | if (!alloc_pixels) | |
532 | RETURN(XpmNoMemory); | |
533 | ||
534 | /* maximum of allocated pixels will be the number of colors */ | |
535 | used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); | |
536 | if (!used_pixels) | |
537 | RETURN(XpmNoMemory); | |
538 | ||
539 | /* get pixel colors, store them in index tables */ | |
540 | ErrorStatus = CreateColors(display, attributes, image->colorTable, | |
541 | image->ncolors, image_pixels, mask_pixels, | |
542 | &mask_pixel_index, alloc_pixels, &nalloc_pixels, | |
543 | used_pixels, &nused_pixels); | |
544 | ||
545 | if (ErrorStatus != XpmSuccess | |
546 | && (ErrorStatus < 0 || (attributes | |
547 | && (attributes->valuemask & XpmExactColors) | |
548 | && attributes->exactColors))) | |
549 | RETURN(ErrorStatus); | |
550 | ||
551 | /* create the ximage */ | |
552 | if (image_return) { | |
553 | ErrorStatus = CreateXImage(display, visual, depth, | |
554 | (depth == 1 ? bitmap_format : ZPixmap), | |
555 | image->width, image->height, &ximage); | |
556 | if (ErrorStatus != XpmSuccess) | |
557 | RETURN(ErrorStatus); | |
558 | ||
559 | PlatformPutImagePixels(display, ximage, image->width, image->height, | |
560 | image->data, image_pixels); | |
561 | ||
562 | } | |
563 | /* create the shape mask image */ | |
564 | if (mask_pixel_index != XpmUndefPixel && shapeimage_return) { | |
565 | ErrorStatus = CreateXImage(display, visual, 1, bitmap_format, | |
566 | image->width, image->height, &shapeimage); | |
567 | if (ErrorStatus != XpmSuccess) | |
568 | RETURN(ErrorStatus); | |
569 | ||
570 | PlatformPutImagePixels(display, shapeimage, image->width, image->height, | |
571 | image->data, mask_pixels); | |
572 | ||
573 | } | |
574 | XpmFree(image_pixels); | |
575 | XpmFree(mask_pixels); | |
576 | ||
577 | /* if requested return used pixels in the XpmAttributes structure */ | |
578 | if (attributes && (attributes->valuemask & XpmReturnPixels || | |
579 | /* 3.2 backward compatibility code */ | |
580 | attributes->valuemask & XpmReturnInfos)) { | |
581 | /* end 3.2 bc */ | |
582 | attributes->pixels = used_pixels; | |
583 | attributes->npixels = nused_pixels; | |
584 | attributes->mask_pixel = mask_pixel_index; | |
585 | } else | |
586 | XpmFree(used_pixels); | |
587 | ||
588 | /* if requested return alloc'ed pixels in the XpmAttributes structure */ | |
589 | if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) { | |
590 | attributes->alloc_pixels = alloc_pixels; | |
591 | attributes->nalloc_pixels = nalloc_pixels; | |
592 | } else | |
593 | XpmFree(alloc_pixels); | |
594 | ||
595 | /* return created images */ | |
596 | if (image_return) | |
597 | *image_return = ximage; | |
598 | if (shapeimage_return) | |
599 | *shapeimage_return = shapeimage; | |
600 | ||
601 | return (ErrorStatus); | |
602 | ||
603 | /* exit point in case of error, free only locally allocated variables */ | |
604 | error: | |
605 | if (ximage) | |
606 | XDestroyImage(ximage); | |
607 | if (shapeimage) | |
608 | XDestroyImage(shapeimage); | |
609 | if (image_pixels) | |
610 | XpmFree(image_pixels); | |
611 | if (mask_pixels) | |
612 | XpmFree(mask_pixels); | |
613 | if (nalloc_pixels) | |
614 | (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL); | |
615 | if (alloc_pixels) | |
616 | XpmFree(alloc_pixels); | |
617 | if (used_pixels) | |
618 | XpmFree(used_pixels); | |
619 | ||
620 | return (ErrorStatus); | |
621 | } | |
622 | ||
623 | ||
624 | /* | |
625 | * Create an XImage with its data | |
626 | */ | |
627 | static int | |
628 | CreateXImage(display, visual, depth, format, width, height, image_return) | |
629 | Display *display; | |
630 | Visual *visual; | |
631 | unsigned int depth; | |
632 | int format; | |
633 | unsigned int width; | |
634 | unsigned int height; | |
635 | XImage **image_return; | |
636 | { | |
637 | int bitmap_pad; | |
638 | ||
639 | /* first get bitmap_pad */ | |
640 | if (depth > 16) | |
641 | bitmap_pad = 32; | |
642 | else if (depth > 8) | |
643 | bitmap_pad = 16; | |
644 | else | |
645 | bitmap_pad = 8; | |
646 | ||
647 | /* then create the XImage with data = NULL and bytes_per_line = 0 */ | |
648 | *image_return = XCreateImage(display, visual, depth, format, 0, 0, | |
649 | width, height, bitmap_pad, 0); | |
650 | if (!*image_return) | |
651 | return (XpmNoMemory); | |
652 | ||
653 | /* XCreateImage has done it all */ | |
654 | ||
655 | return (XpmSuccess); | |
656 | } | |
657 | ||
658 | static void | |
659 | PlatformPutImagePixels(dc, image, width, height, pixelindex, pixels) | |
660 | Display *dc; | |
661 | XImage *image; | |
662 | unsigned int width; | |
663 | unsigned int height; | |
664 | unsigned int *pixelindex; | |
665 | Pixel *pixels; | |
666 | { | |
667 | ||
668 | #ifdef FOR_MSW | |
669 | unsigned int *data = pixelindex; | |
670 | unsigned int x, y; | |
671 | HBITMAP obm; | |
672 | ||
673 | obm = SelectObject(*dc, image->bitmap); | |
674 | for (y = 0; y < height; y++) { | |
675 | for (x = 0; x < width; x++) { | |
676 | SetPixel(*dc, x, y, pixels[*(data++)]); // data is [x+y*width] | |
677 | } | |
678 | } | |
679 | SelectObject(*dc, obm); | |
680 | #elif macintosh | |
681 | GrafPtr origPort ; | |
682 | GDHandle origDevice ; | |
683 | ||
684 | unsigned int *data = pixelindex; | |
685 | unsigned int x, y; | |
686 | ||
687 | GetGWorld( &origPort , &origDevice ) ; | |
688 | SetGWorld( image->gworldptr , NULL ) ; | |
689 | ||
690 | for (y = 0; y < height; y++) | |
691 | { | |
692 | for (x = 0; x < width; x++) | |
693 | { | |
694 | SetCPixel( x, y, &pixels[*(data++)]); // data is [x+y*width] | |
695 | } | |
696 | } | |
697 | SetGWorld( origPort , origDevice ) ; | |
698 | #endif | |
699 | } | |
700 | ||
701 | /* | |
702 | * This function parses an Xpm file or data and directly create an XImage | |
703 | */ | |
704 | int | |
705 | xpmParseDataAndCreate(display, data, image_return, shapeimage_return, | |
706 | image, info, attributes) | |
707 | Display *display; | |
708 | xpmData *data; | |
709 | XImage **image_return; | |
710 | XImage **shapeimage_return; | |
711 | XpmImage *image; | |
712 | XpmInfo *info; | |
713 | XpmAttributes *attributes; | |
714 | { | |
715 | /* variables stored in the XpmAttributes structure */ | |
716 | Visual *visual; | |
717 | Colormap colormap; | |
718 | unsigned int depth; | |
719 | int bitmap_format; | |
720 | XpmFreeColorsFunc freeColors; | |
721 | void *closure; | |
722 | ||
723 | /* variables to return */ | |
724 | XImage *ximage = NULL; | |
725 | XImage *shapeimage = NULL; | |
726 | unsigned int mask_pixel_index = XpmUndefPixel; | |
727 | ||
728 | /* calculation variables */ | |
729 | Pixel *image_pixels = NULL; | |
730 | Pixel *mask_pixels = NULL; | |
731 | Pixel *alloc_pixels = NULL; | |
732 | Pixel *used_pixels = NULL; | |
733 | unsigned int nalloc_pixels = 0; | |
734 | unsigned int nused_pixels = 0; | |
735 | unsigned int width, height, ncolors, cpp; | |
736 | unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0; | |
737 | XpmColor *colorTable = NULL; | |
738 | char *hints_cmt = NULL; | |
739 | char *colors_cmt = NULL; | |
740 | char *pixels_cmt = NULL; | |
741 | ||
742 | unsigned int cmts; | |
743 | int ErrorStatus; | |
744 | xpmHashTable hashtable; | |
745 | ||
746 | ||
747 | /* initialize return values */ | |
748 | if (image_return) | |
749 | *image_return = NULL; | |
750 | if (shapeimage_return) | |
751 | *shapeimage_return = NULL; | |
752 | ||
753 | ||
754 | /* retrieve information from the XpmAttributes */ | |
755 | if (attributes && (attributes->valuemask & XpmVisual)) | |
756 | visual = attributes->visual; | |
757 | else | |
758 | visual = XDefaultVisual(display, XDefaultScreen(display)); | |
759 | ||
760 | if (attributes && (attributes->valuemask & XpmColormap)) | |
761 | colormap = attributes->colormap; | |
762 | else | |
763 | colormap = XDefaultColormap(display, XDefaultScreen(display)); | |
764 | ||
765 | if (attributes && (attributes->valuemask & XpmDepth)) | |
766 | depth = attributes->depth; | |
767 | else | |
768 | depth = XDefaultDepth(display, XDefaultScreen(display)); | |
769 | ||
770 | if (attributes && (attributes->valuemask & XpmBitmapFormat)) | |
771 | bitmap_format = attributes->bitmap_format; | |
772 | else | |
773 | bitmap_format = ZPixmap; | |
774 | ||
775 | if (attributes && (attributes->valuemask & XpmFreeColors)) | |
776 | freeColors = attributes->free_colors; | |
777 | else | |
778 | freeColors = FreeColors; | |
779 | if (attributes && (attributes->valuemask & XpmColorClosure)) | |
780 | closure = attributes->color_closure; | |
781 | else | |
782 | closure = NULL; | |
783 | ||
784 | cmts = info && (info->valuemask & XpmReturnComments); | |
785 | ||
786 | /* | |
787 | * parse the header | |
788 | */ | |
789 | ErrorStatus = xpmParseHeader(data); | |
790 | if (ErrorStatus != XpmSuccess) | |
791 | return (ErrorStatus); | |
792 | ||
793 | /* | |
794 | * read values | |
795 | */ | |
796 | ErrorStatus = xpmParseValues(data, &width, &height, &ncolors, &cpp, | |
797 | &x_hotspot, &y_hotspot, &hotspot, | |
798 | &extensions); | |
799 | if (ErrorStatus != XpmSuccess) | |
800 | return (ErrorStatus); | |
801 | ||
802 | /* | |
803 | * store the hints comment line | |
804 | */ | |
805 | if (cmts) | |
806 | xpmGetCmt(data, &hints_cmt); | |
807 | ||
808 | /* | |
809 | * init the hastable | |
810 | */ | |
811 | if (USE_HASHTABLE) { | |
812 | ErrorStatus = xpmHashTableInit(&hashtable); | |
813 | if (ErrorStatus != XpmSuccess) | |
814 | return (ErrorStatus); | |
815 | } | |
816 | ||
817 | /* | |
818 | * read colors | |
819 | */ | |
820 | ErrorStatus = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable); | |
821 | if (ErrorStatus != XpmSuccess) | |
822 | RETURN(ErrorStatus); | |
823 | ||
824 | /* | |
825 | * store the colors comment line | |
826 | */ | |
827 | if (cmts) | |
828 | xpmGetCmt(data, &colors_cmt); | |
829 | ||
830 | /* malloc pixels index tables */ | |
831 | image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); | |
832 | if (!image_pixels) | |
833 | RETURN(XpmNoMemory); | |
834 | ||
835 | mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); | |
836 | if (!mask_pixels) | |
837 | RETURN(XpmNoMemory); | |
838 | ||
839 | /* maximum of allocated pixels will be the number of colors */ | |
840 | alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); | |
841 | if (!alloc_pixels) | |
842 | RETURN(XpmNoMemory); | |
843 | ||
844 | /* maximum of allocated pixels will be the number of colors */ | |
845 | used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); | |
846 | if (!used_pixels) | |
847 | RETURN(XpmNoMemory); | |
848 | ||
849 | /* get pixel colors, store them in index tables */ | |
850 | ErrorStatus = CreateColors(display, attributes, colorTable, ncolors, | |
851 | image_pixels, mask_pixels, &mask_pixel_index, | |
852 | alloc_pixels, &nalloc_pixels, used_pixels, | |
853 | &nused_pixels); | |
854 | ||
855 | if (ErrorStatus != XpmSuccess | |
856 | && (ErrorStatus < 0 || (attributes | |
857 | && (attributes->valuemask & XpmExactColors) | |
858 | && attributes->exactColors))) | |
859 | RETURN(ErrorStatus); | |
860 | ||
861 | /* now create the ximage */ | |
862 | if (image_return) { | |
863 | ErrorStatus = CreateXImage(display, visual, depth, | |
864 | (depth == 1 ? bitmap_format : ZPixmap), | |
865 | width, height, &ximage); | |
866 | if (ErrorStatus != XpmSuccess) | |
867 | RETURN(ErrorStatus); | |
868 | ||
869 | } | |
870 | ||
871 | /* create the shape mask image */ | |
872 | if (mask_pixel_index != XpmUndefPixel && shapeimage_return) { | |
873 | ErrorStatus = CreateXImage(display, visual, 1, bitmap_format, | |
874 | width, height, &shapeimage); | |
875 | if (ErrorStatus != XpmSuccess) | |
876 | RETURN(ErrorStatus); | |
877 | ||
878 | } | |
879 | ||
880 | /* | |
881 | * read pixels and put them in the XImage | |
882 | */ | |
883 | ErrorStatus = ParseAndPutPixels( | |
884 | display, | |
885 | data, width, height, ncolors, cpp, | |
886 | colorTable, &hashtable, | |
887 | ximage, image_pixels, | |
888 | shapeimage, mask_pixels); | |
889 | XpmFree(image_pixels); | |
890 | image_pixels = NULL; | |
891 | XpmFree(mask_pixels); | |
892 | mask_pixels = NULL; | |
893 | ||
894 | /* | |
895 | * free the hastable | |
896 | */ | |
897 | if (ErrorStatus != XpmSuccess) | |
898 | RETURN(ErrorStatus) | |
899 | else if (USE_HASHTABLE) | |
900 | xpmHashTableFree(&hashtable); | |
901 | ||
902 | /* | |
903 | * store the pixels comment line | |
904 | */ | |
905 | if (cmts) | |
906 | xpmGetCmt(data, &pixels_cmt); | |
907 | ||
908 | /* | |
909 | * parse extensions | |
910 | */ | |
911 | if (info && (info->valuemask & XpmReturnExtensions)) | |
912 | if (extensions) { | |
913 | ErrorStatus = xpmParseExtensions(data, &info->extensions, | |
914 | &info->nextensions); | |
915 | if (ErrorStatus != XpmSuccess) | |
916 | RETURN(ErrorStatus); | |
917 | } else { | |
918 | info->extensions = NULL; | |
919 | info->nextensions = 0; | |
920 | } | |
921 | ||
922 | /* | |
923 | * store found informations in the XpmImage structure | |
924 | */ | |
925 | image->width = width; | |
926 | image->height = height; | |
927 | image->cpp = cpp; | |
928 | image->ncolors = ncolors; | |
929 | image->colorTable = colorTable; | |
930 | image->data = NULL; | |
931 | ||
932 | if (info) { | |
933 | if (cmts) { | |
934 | info->hints_cmt = hints_cmt; | |
935 | info->colors_cmt = colors_cmt; | |
936 | info->pixels_cmt = pixels_cmt; | |
937 | } | |
938 | if (hotspot) { | |
939 | info->x_hotspot = x_hotspot; | |
940 | info->y_hotspot = y_hotspot; | |
941 | info->valuemask |= XpmHotspot; | |
942 | } | |
943 | } | |
944 | /* if requested return used pixels in the XpmAttributes structure */ | |
945 | if (attributes && (attributes->valuemask & XpmReturnPixels || | |
946 | /* 3.2 backward compatibility code */ | |
947 | attributes->valuemask & XpmReturnInfos)) { | |
948 | /* end 3.2 bc */ | |
949 | attributes->pixels = used_pixels; | |
950 | attributes->npixels = nused_pixels; | |
951 | attributes->mask_pixel = mask_pixel_index; | |
952 | } else | |
953 | XpmFree(used_pixels); | |
954 | ||
955 | /* if requested return alloc'ed pixels in the XpmAttributes structure */ | |
956 | if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) { | |
957 | attributes->alloc_pixels = alloc_pixels; | |
958 | attributes->nalloc_pixels = nalloc_pixels; | |
959 | } else | |
960 | XpmFree(alloc_pixels); | |
961 | ||
962 | /* return created images */ | |
963 | if (image_return) | |
964 | *image_return = ximage; | |
965 | if (shapeimage_return) | |
966 | *shapeimage_return = shapeimage; | |
967 | ||
968 | return (XpmSuccess); | |
969 | ||
970 | /* exit point in case of error, free only locally allocated variables */ | |
971 | error: | |
972 | if (USE_HASHTABLE) | |
973 | xpmHashTableFree(&hashtable); | |
974 | if (colorTable) | |
975 | xpmFreeColorTable(colorTable, ncolors); | |
976 | if (hints_cmt) | |
977 | XpmFree(hints_cmt); | |
978 | if (colors_cmt) | |
979 | XpmFree(colors_cmt); | |
980 | if (pixels_cmt) | |
981 | XpmFree(pixels_cmt); | |
982 | if (ximage) | |
983 | XDestroyImage(ximage); | |
984 | if (shapeimage) | |
985 | XDestroyImage(shapeimage); | |
986 | if (image_pixels) | |
987 | XpmFree(image_pixels); | |
988 | if (mask_pixels) | |
989 | XpmFree(mask_pixels); | |
990 | if (nalloc_pixels) | |
991 | (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL); | |
992 | if (alloc_pixels) | |
993 | XpmFree(alloc_pixels); | |
994 | if (used_pixels) | |
995 | XpmFree(used_pixels); | |
996 | ||
997 | return (ErrorStatus); | |
998 | } | |
999 | ||
1000 | static int | |
1001 | ParseAndPutPixels( | |
1002 | dc, | |
1003 | data, width, height, ncolors, cpp, colorTable, hashtable, | |
1004 | image, image_pixels, shapeimage, shape_pixels) | |
1005 | Display *dc; | |
1006 | xpmData *data; | |
1007 | unsigned int width; | |
1008 | unsigned int height; | |
1009 | unsigned int ncolors; | |
1010 | unsigned int cpp; | |
1011 | XpmColor *colorTable; | |
1012 | xpmHashTable *hashtable; | |
1013 | XImage *image; | |
1014 | Pixel *image_pixels; | |
1015 | XImage *shapeimage; | |
1016 | Pixel *shape_pixels; | |
1017 | { | |
1018 | unsigned int a, x, y; | |
1019 | ||
1020 | switch (cpp) { | |
1021 | ||
1022 | case (1): /* Optimize for single character | |
1023 | * colors */ | |
1024 | { | |
1025 | unsigned short colidx[256]; | |
1026 | #ifdef FOR_MSW | |
1027 | ||
1028 | HDC shapedc; | |
1029 | HBITMAP obm, sobm; | |
1030 | ||
1031 | if ( shapeimage ) { | |
1032 | shapedc = CreateCompatibleDC(*dc); | |
1033 | sobm = SelectObject(shapedc, shapeimage->bitmap); | |
1034 | } else { | |
1035 | shapedc = NULL; | |
1036 | } | |
1037 | obm = SelectObject(*dc, image->bitmap); | |
1038 | ||
1039 | #elif macintosh | |
1040 | GrafPtr origPort ; | |
1041 | GDHandle origDevice ; | |
1042 | ||
1043 | GetGWorld( &origPort , &origDevice ) ; | |
1044 | // ignore shapedc | |
1045 | SetGWorld( image->gworldptr , NULL ) ; | |
1046 | ||
1047 | #endif | |
1048 | ||
1049 | bzero((char *)colidx, 256 * sizeof(short)); | |
1050 | for (a = 0; a < ncolors; a++) | |
1051 | colidx[(unsigned char)colorTable[a].string[0]] = a + 1; | |
1052 | ||
1053 | for (y = 0; y < height; y++) | |
1054 | { | |
1055 | xpmNextString(data); | |
1056 | for (x = 0; x < width; x++) | |
1057 | { | |
1058 | int c = xpmGetC(data); | |
1059 | ||
1060 | if (c > 0 && c < 256 && colidx[c] != 0) | |
1061 | { | |
1062 | #if FOR_MSW | |
1063 | SetPixel(*dc, x, y, image_pixels[colidx[c] - 1]); | |
1064 | if (shapedc) | |
1065 | { | |
1066 | SetPixel(shapedc, x, y, shape_pixels[colidx[c] - 1]); | |
1067 | } | |
1068 | #elif macintosh | |
1069 | SetCPixel( x, y, &image_pixels[colidx[c] - 1]); | |
1070 | /* | |
1071 | if (shapedc) | |
1072 | { | |
1073 | SetPixel(shapedc, x, y, shape_pixels[colidx[c] - 1]); | |
1074 | } | |
1075 | */ | |
1076 | #endif | |
1077 | } | |
1078 | else | |
1079 | return (XpmFileInvalid); | |
1080 | } | |
1081 | } | |
1082 | #if FOR_MSW | |
1083 | if ( shapedc ) | |
1084 | { | |
1085 | SelectObject(shapedc, sobm); | |
1086 | DeleteDC(shapedc); | |
1087 | } | |
1088 | SelectObject(*dc, obm); | |
1089 | #elif macintosh | |
1090 | SetGWorld( origPort , origDevice ) ; | |
1091 | #endif | |
1092 | } | |
1093 | break; | |
1094 | ||
1095 | case (2): /* Optimize for double character | |
1096 | * colors */ | |
1097 | { | |
1098 | ||
1099 | /* free all allocated pointers at all exits */ | |
1100 | #define FREE_CIDX {int f; for (f = 0; f < 256; f++) \ | |
1101 | if (cidx[f]) XpmFree(cidx[f]);} | |
1102 | ||
1103 | /* array of pointers malloced by need */ | |
1104 | unsigned short *cidx[256]; | |
1105 | int char1; | |
1106 | #ifdef macintosh | |
1107 | GrafPtr origPort ; | |
1108 | GDHandle origDevice ; | |
1109 | GetGWorld( &origPort , &origDevice ) ; | |
1110 | SetGWorld( image->gworldptr , NULL ) ; | |
1111 | #endif | |
1112 | bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */ | |
1113 | for (a = 0; a < ncolors; a++) { | |
1114 | char1 = colorTable[a].string[0]; | |
1115 | if (cidx[char1] == NULL) { /* get new memory */ | |
1116 | cidx[char1] = (unsigned short *) | |
1117 | XpmCalloc(256, sizeof(unsigned short)); | |
1118 | if (cidx[char1] == NULL) { /* new block failed */ | |
1119 | #ifdef macintosh | |
1120 | SetGWorld( origPort , origDevice ) ; | |
1121 | #endif | |
1122 | FREE_CIDX; | |
1123 | return (XpmNoMemory); | |
1124 | } | |
1125 | } | |
1126 | cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1; | |
1127 | } | |
1128 | ||
1129 | for (y = 0; y < height; y++) { | |
1130 | xpmNextString(data); | |
1131 | for (x = 0; x < width; x++) | |
1132 | { | |
1133 | int cc1 = xpmGetC(data); | |
1134 | if (cc1 > 0 && cc1 < 256) { | |
1135 | int cc2 = xpmGetC(data); | |
1136 | if (cc2 > 0 && cc2 < 256 && | |
1137 | cidx[cc1] && cidx[cc1][cc2] != 0) { | |
1138 | ||
1139 | #ifdef FOR_MSW | |
1140 | SelectObject(*dc, image->bitmap); | |
1141 | SetPixel(*dc, x, y, image_pixels[cidx[cc1][cc2] - 1]); | |
1142 | if (shapeimage) | |
1143 | { | |
1144 | SelectObject(*dc, shapeimage->bitmap); | |
1145 | SetPixel(*dc, x, y, | |
1146 | shape_pixels[cidx[cc1][cc2] - 1]); | |
1147 | } | |
1148 | #elif macintosh | |
1149 | SetCPixel( x, y, &image_pixels[cidx[cc1][cc2] - 1]); | |
1150 | #endif | |
1151 | } else | |
1152 | { | |
1153 | #ifdef macintosh | |
1154 | SetGWorld( origPort , origDevice ) ; | |
1155 | #endif | |
1156 | FREE_CIDX; | |
1157 | return (XpmFileInvalid); | |
1158 | } | |
1159 | } else { | |
1160 | #ifdef macintosh | |
1161 | SetGWorld( origPort , origDevice ) ; | |
1162 | #endif | |
1163 | FREE_CIDX; | |
1164 | return (XpmFileInvalid); | |
1165 | } | |
1166 | } | |
1167 | } | |
1168 | #ifdef macintosh | |
1169 | SetGWorld( origPort , origDevice ) ; | |
1170 | #endif | |
1171 | FREE_CIDX; | |
1172 | } | |
1173 | break; | |
1174 | ||
1175 | default: /* Non-optimized case of long color | |
1176 | * names */ | |
1177 | { | |
1178 | char *s; | |
1179 | char buf[BUFSIZ]; | |
1180 | #ifdef macintosh | |
1181 | GrafPtr origPort ; | |
1182 | GDHandle origDevice ; | |
1183 | GetGWorld( &origPort , &origDevice ) ; | |
1184 | SetGWorld( image->gworldptr , NULL ) ; | |
1185 | #endif | |
1186 | ||
1187 | buf[cpp] = '\0'; | |
1188 | if (USE_HASHTABLE) { | |
1189 | xpmHashAtom *slot; | |
1190 | ||
1191 | for (y = 0; y < height; y++) { | |
1192 | xpmNextString(data); | |
1193 | for (x = 0; x < width; x++) { | |
1194 | for (a = 0, s = buf; a < cpp; a++, s++) | |
1195 | *s = xpmGetC(data); | |
1196 | slot = xpmHashSlot(hashtable, buf); | |
1197 | if (!*slot) /* no color matches */ | |
1198 | { | |
1199 | #ifdef macintosh | |
1200 | SetGWorld( origPort , origDevice ) ; | |
1201 | #endif | |
1202 | return (XpmFileInvalid); | |
1203 | } | |
1204 | ||
1205 | #if FOR_MSW | |
1206 | SelectObject(*dc, image->bitmap); | |
1207 | SetPixel(*dc, x, y, | |
1208 | image_pixels[HashColorIndex(slot)]); | |
1209 | if (shapeimage) | |
1210 | { | |
1211 | SelectObject(*dc, shapeimage->bitmap); | |
1212 | SetPixel(*dc, x, y, | |
1213 | shape_pixels[HashColorIndex(slot)]); | |
1214 | } | |
1215 | #elif macintosh | |
1216 | SetCPixel( x, y, &image_pixels[HashColorIndex(slot)]); | |
1217 | #endif | |
1218 | } | |
1219 | } | |
1220 | } else { | |
1221 | for (y = 0; y < height; y++) { | |
1222 | xpmNextString(data); | |
1223 | for (x = 0; x < width; x++) { | |
1224 | for (a = 0, s = buf; a < cpp; a++, s++) | |
1225 | *s = xpmGetC(data); | |
1226 | for (a = 0; a < ncolors; a++) | |
1227 | if (!strcmp(colorTable[a].string, buf)) | |
1228 | break; | |
1229 | if (a == ncolors) /* no color matches */ | |
1230 | { | |
1231 | #ifdef macintosh | |
1232 | SetGWorld( origPort , origDevice ) ; | |
1233 | #endif | |
1234 | return (XpmFileInvalid); | |
1235 | } | |
1236 | ||
1237 | #if FOR_MSW | |
1238 | SelectObject(*dc, image->bitmap); | |
1239 | SetPixel(*dc, x, y, image_pixels[a]); | |
1240 | if (shapeimage) { | |
1241 | SelectObject(*dc, shapeimage->bitmap); | |
1242 | SetPixel(*dc, x, y, shape_pixels[a]); | |
1243 | } | |
1244 | #elif macintosh | |
1245 | SetCPixel( x, y, &image_pixels[a]); // data is [x+y*width] | |
1246 | #endif | |
1247 | } | |
1248 | } | |
1249 | } | |
1250 | #ifdef macintosh | |
1251 | SetGWorld( origPort , origDevice ) ; | |
1252 | #endif | |
1253 | ||
1254 | } | |
1255 | break; | |
1256 | } | |
1257 | return (XpmSuccess); | |
1258 | } |