1a966c04fSmrg/* 2a966c04fSmrg * Copyright (C) 1989-95 GROUPE BULL 3a966c04fSmrg * 4a966c04fSmrg * Permission is hereby granted, free of charge, to any person obtaining a copy 5a966c04fSmrg * of this software and associated documentation files (the "Software"), to 6a966c04fSmrg * deal in the Software without restriction, including without limitation the 7a966c04fSmrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8a966c04fSmrg * sell copies of the Software, and to permit persons to whom the Software is 9a966c04fSmrg * furnished to do so, subject to the following conditions: 10a966c04fSmrg * 11a966c04fSmrg * The above copyright notice and this permission notice shall be included in 12a966c04fSmrg * all copies or substantial portions of the Software. 13a966c04fSmrg * 14a966c04fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15a966c04fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16a966c04fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17a966c04fSmrg * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18a966c04fSmrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19a966c04fSmrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20a966c04fSmrg * 21a966c04fSmrg * Except as contained in this notice, the name of GROUPE BULL shall not be 22a966c04fSmrg * used in advertising or otherwise to promote the sale, use or other dealings 23a966c04fSmrg * in this Software without prior written authorization from GROUPE BULL. 24a966c04fSmrg */ 25a966c04fSmrg 26a966c04fSmrg/*****************************************************************************\ 27a966c04fSmrg* create.c: * 28a966c04fSmrg* * 29a966c04fSmrg* XPM library * 30a966c04fSmrg* Create an X image and possibly its related shape mask * 31a966c04fSmrg* from the given XpmImage. * 32a966c04fSmrg* * 33a966c04fSmrg* Developed by Arnaud Le Hors * 34a966c04fSmrg\*****************************************************************************/ 35a966c04fSmrg 36a966c04fSmrg/* 37a966c04fSmrg * The code related to FOR_MSW has been added by 38a966c04fSmrg * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 39a966c04fSmrg */ 40a966c04fSmrg 41a966c04fSmrg/* 42a966c04fSmrg * The code related to AMIGA has been added by 43a966c04fSmrg * Lorens Younes (d93-hyo@nada.kth.se) 4/96 44a966c04fSmrg */ 45a966c04fSmrg 46a966c04fSmrg/* October 2004, source code review by Thomas Biege <thomas@suse.de> */ 47a966c04fSmrg 48a966c04fSmrg#ifdef HAVE_CONFIG_H 49a966c04fSmrg#include <config.h> 50a966c04fSmrg#endif 51a966c04fSmrg#include "XpmI.h" 52a966c04fSmrg#include <ctype.h> 53a966c04fSmrg 54a966c04fSmrgLFUNC(xpmVisualType, int, (Visual *visual)); 55a966c04fSmrg 56a966c04fSmrgLFUNC(AllocColor, int, (Display *display, Colormap colormap, 57a966c04fSmrg char *colorname, XColor *xcolor, void *closure)); 58a966c04fSmrgLFUNC(FreeColors, int, (Display *display, Colormap colormap, 59a966c04fSmrg Pixel *pixels, int n, void *closure)); 60a966c04fSmrg 61a966c04fSmrg#ifndef FOR_MSW 62a966c04fSmrgLFUNC(SetCloseColor, int, (Display *display, Colormap colormap, 63a966c04fSmrg Visual *visual, XColor *col, 64a966c04fSmrg Pixel *image_pixel, Pixel *mask_pixel, 65a966c04fSmrg Pixel *alloc_pixels, unsigned int *nalloc_pixels, 66a966c04fSmrg XpmAttributes *attributes, XColor *cols, int ncols, 67a966c04fSmrg XpmAllocColorFunc allocColor, void *closure)); 68a966c04fSmrg#else 69a966c04fSmrg/* let the window system take care of close colors */ 70a966c04fSmrg#endif 71a966c04fSmrg 72a966c04fSmrgLFUNC(SetColor, int, (Display *display, Colormap colormap, Visual *visual, 73a966c04fSmrg char *colorname, unsigned int color_index, 74a966c04fSmrg Pixel *image_pixel, Pixel *mask_pixel, 75a966c04fSmrg unsigned int *mask_pixel_index, 76a966c04fSmrg Pixel *alloc_pixels, unsigned int *nalloc_pixels, 77a966c04fSmrg Pixel *used_pixels, unsigned int *nused_pixels, 78a966c04fSmrg XpmAttributes *attributes, XColor *cols, int ncols, 79a966c04fSmrg XpmAllocColorFunc allocColor, void *closure)); 80a966c04fSmrg 81a966c04fSmrgLFUNC(CreateXImage, int, (Display *display, Visual *visual, 82a966c04fSmrg unsigned int depth, int format, unsigned int width, 83a966c04fSmrg unsigned int height, XImage **image_return)); 84a966c04fSmrg 85a966c04fSmrgLFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes, 86a966c04fSmrg XpmColor *colors, unsigned int ncolors, 87a966c04fSmrg Pixel *image_pixels, Pixel *mask_pixels, 88a966c04fSmrg unsigned int *mask_pixel_index, 89a966c04fSmrg Pixel *alloc_pixels, unsigned int *nalloc_pixels, 90a966c04fSmrg Pixel *used_pixels, unsigned int *nused_pixels)); 91a966c04fSmrg 92a966c04fSmrg#ifndef FOR_MSW 93a966c04fSmrgLFUNC(ParseAndPutPixels, int, (xpmData *data, unsigned int width, 94a966c04fSmrg unsigned int height, unsigned int ncolors, 95a966c04fSmrg unsigned int cpp, XpmColor *colorTable, 96a966c04fSmrg xpmHashTable *hashtable, 97a966c04fSmrg XImage *image, Pixel *image_pixels, 98a966c04fSmrg XImage *mask, Pixel *mask_pixels)); 99a966c04fSmrg#else /* FOR_MSW */ 100a966c04fSmrgLFUNC(ParseAndPutPixels, int, (Display *dc, xpmData *data, unsigned int width, 101a966c04fSmrg unsigned int height, unsigned int ncolors, 102a966c04fSmrg unsigned int cpp, XpmColor *colorTable, 103a966c04fSmrg xpmHashTable *hashtable, 104a966c04fSmrg XImage *image, Pixel *image_pixels, 105a966c04fSmrg XImage *mask, Pixel *mask_pixels)); 106a966c04fSmrg#endif 107a966c04fSmrg 108a966c04fSmrg#ifndef FOR_MSW 109a966c04fSmrg# ifndef AMIGA 110a966c04fSmrg/* XImage pixel routines */ 111a966c04fSmrgLFUNC(PutImagePixels, void, (XImage *image, unsigned int width, 112a966c04fSmrg unsigned int height, unsigned int *pixelindex, 113a966c04fSmrg Pixel *pixels)); 114a966c04fSmrg 115a966c04fSmrgLFUNC(PutImagePixels32, void, (XImage *image, unsigned int width, 116a966c04fSmrg unsigned int height, unsigned int *pixelindex, 117a966c04fSmrg Pixel *pixels)); 118a966c04fSmrg 119a966c04fSmrgLFUNC(PutImagePixels16, void, (XImage *image, unsigned int width, 120a966c04fSmrg unsigned int height, unsigned int *pixelindex, 121a966c04fSmrg Pixel *pixels)); 122a966c04fSmrg 123a966c04fSmrgLFUNC(PutImagePixels8, void, (XImage *image, unsigned int width, 124a966c04fSmrg unsigned int height, unsigned int *pixelindex, 125a966c04fSmrg Pixel *pixels)); 126a966c04fSmrg 127a966c04fSmrgLFUNC(PutImagePixels1, void, (XImage *image, unsigned int width, 128a966c04fSmrg unsigned int height, unsigned int *pixelindex, 129a966c04fSmrg Pixel *pixels)); 130a966c04fSmrg 131a966c04fSmrgLFUNC(PutPixel1, int, (XImage *ximage, int x, int y, unsigned long pixel)); 132a966c04fSmrgLFUNC(PutPixel, int, (XImage *ximage, int x, int y, unsigned long pixel)); 133a966c04fSmrg#if !defined(WORD64) && !defined(LONG64) 134a966c04fSmrgLFUNC(PutPixel32, int, (XImage *ximage, int x, int y, unsigned long pixel)); 135a966c04fSmrg#endif 136a966c04fSmrgLFUNC(PutPixel32MSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); 137a966c04fSmrgLFUNC(PutPixel32LSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); 138a966c04fSmrgLFUNC(PutPixel16MSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); 139a966c04fSmrgLFUNC(PutPixel16LSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); 140a966c04fSmrgLFUNC(PutPixel8, int, (XImage *ximage, int x, int y, unsigned long pixel)); 141a966c04fSmrgLFUNC(PutPixel1MSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); 142a966c04fSmrgLFUNC(PutPixel1LSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); 143a966c04fSmrg 144a966c04fSmrg# else /* AMIGA */ 145a966c04fSmrgLFUNC(APutImagePixels, void, (XImage *ximage, unsigned int width, 146a966c04fSmrg unsigned int height, unsigned int *pixelindex, 147a966c04fSmrg Pixel *pixels)); 148a966c04fSmrg# endif/* AMIGA */ 149a966c04fSmrg#else /* FOR_MSW */ 150a966c04fSmrg/* FOR_MSW pixel routine */ 151a966c04fSmrgLFUNC(MSWPutImagePixels, void, (Display *dc, XImage *image, 152a966c04fSmrg unsigned int width, unsigned int height, 153a966c04fSmrg unsigned int *pixelindex, Pixel *pixels)); 154a966c04fSmrg#endif /* FOR_MSW */ 155a966c04fSmrg 156a966c04fSmrg#ifdef NEED_STRCASECMP 157a966c04fSmrgFUNC(xpmstrcasecmp, int, (char *s1, char *s2)); 158a966c04fSmrg 159a966c04fSmrg/* 160a966c04fSmrg * in case strcasecmp is not provided by the system here is one 161a966c04fSmrg * which does the trick 162a966c04fSmrg */ 163a966c04fSmrgint 1642e2dd055Smrgxpmstrcasecmp( 1652e2dd055Smrg register char *s1, 1662e2dd055Smrg register char *s2) 167a966c04fSmrg{ 168a966c04fSmrg register int c1, c2; 169a966c04fSmrg 170a966c04fSmrg while (*s1 && *s2) { 171a966c04fSmrg c1 = tolower(*s1); 172a966c04fSmrg c2 = tolower(*s2); 173a966c04fSmrg if (c1 != c2) 174a966c04fSmrg return (c1 - c2); 175a966c04fSmrg s1++; 176a966c04fSmrg s2++; 177a966c04fSmrg } 178a966c04fSmrg return (int) (*s1 - *s2); 179a966c04fSmrg} 180a966c04fSmrg 181a966c04fSmrg#endif 182a966c04fSmrg 183a966c04fSmrg/* 184a966c04fSmrg * return the default color key related to the given visual 185a966c04fSmrg */ 186a966c04fSmrgstatic int 1872e2dd055SmrgxpmVisualType(Visual *visual) 188a966c04fSmrg{ 189a966c04fSmrg#ifndef FOR_MSW 190a966c04fSmrg# ifndef AMIGA 191a966c04fSmrg switch (visual->class) { 192a966c04fSmrg case StaticGray: 193a966c04fSmrg case GrayScale: 194a966c04fSmrg switch (visual->map_entries) { 195a966c04fSmrg case 2: 196a966c04fSmrg return (XPM_MONO); 197a966c04fSmrg case 4: 198a966c04fSmrg return (XPM_GRAY4); 199a966c04fSmrg default: 200a966c04fSmrg return (XPM_GRAY); 201a966c04fSmrg } 202a966c04fSmrg default: 203a966c04fSmrg return (XPM_COLOR); 204a966c04fSmrg } 205a966c04fSmrg# else 206a966c04fSmrg /* set the key explicitly in the XpmAttributes to override this */ 207a966c04fSmrg return (XPM_COLOR); 208a966c04fSmrg# endif 209a966c04fSmrg#else 210a966c04fSmrg /* there should be a similar switch for MSW */ 211a966c04fSmrg return (XPM_COLOR); 212a966c04fSmrg#endif 213a966c04fSmrg} 214a966c04fSmrg 215a966c04fSmrg 216a966c04fSmrgtypedef struct { 217a966c04fSmrg int cols_index; 218a966c04fSmrg long closeness; 219a966c04fSmrg} CloseColor; 220a966c04fSmrg 221a966c04fSmrgstatic int 22297cf2ee2Smrgcloseness_cmp(const void *a, const void *b) 223a966c04fSmrg{ 22497cf2ee2Smrg const CloseColor *x = (const CloseColor *) a, *y = (const CloseColor *) b; 225a966c04fSmrg 226a966c04fSmrg /* cast to int as qsort requires */ 227a966c04fSmrg return (int) (x->closeness - y->closeness); 228a966c04fSmrg} 229a966c04fSmrg 230a966c04fSmrg 231a966c04fSmrg/* default AllocColor function: 232a966c04fSmrg * call XParseColor if colorname is given, return negative value if failure 233a966c04fSmrg * call XAllocColor and return 0 if failure, positive otherwise 234a966c04fSmrg */ 235a966c04fSmrgstatic int 2362e2dd055SmrgAllocColor( 2372e2dd055Smrg Display *display, 2382e2dd055Smrg Colormap colormap, 2392e2dd055Smrg char *colorname, 2402e2dd055Smrg XColor *xcolor, 2412e2dd055Smrg void *closure) /* not used */ 242a966c04fSmrg{ 243a966c04fSmrg int status; 244a966c04fSmrg if (colorname) 245a966c04fSmrg if (!XParseColor(display, colormap, colorname, xcolor)) 246a966c04fSmrg return -1; 247a966c04fSmrg status = XAllocColor(display, colormap, xcolor); 248a966c04fSmrg return status != 0 ? 1 : 0; 249a966c04fSmrg} 250a966c04fSmrg 251a966c04fSmrg 252a966c04fSmrg#ifndef FOR_MSW 253a966c04fSmrg/* 254a966c04fSmrg * set a close color in case the exact one can't be set 255a966c04fSmrg * return 0 if success, 1 otherwise. 256a966c04fSmrg */ 257a966c04fSmrg 258a966c04fSmrgstatic int 2592e2dd055SmrgSetCloseColor( 2602e2dd055Smrg Display *display, 2612e2dd055Smrg Colormap colormap, 2622e2dd055Smrg Visual *visual, 2632e2dd055Smrg XColor *col, 2642e2dd055Smrg Pixel *image_pixel, 2652e2dd055Smrg Pixel *mask_pixel, 2662e2dd055Smrg Pixel *alloc_pixels, 2672e2dd055Smrg unsigned int *nalloc_pixels, 2682e2dd055Smrg XpmAttributes *attributes, 2692e2dd055Smrg XColor *cols, 2702e2dd055Smrg int ncols, 2712e2dd055Smrg XpmAllocColorFunc allocColor, 2722e2dd055Smrg void *closure) 273a966c04fSmrg{ 274a966c04fSmrg 275a966c04fSmrg /* 276a966c04fSmrg * Allocation failed, so try close colors. To get here the visual must 277a966c04fSmrg * be GreyScale, PseudoColor or DirectColor (or perhaps StaticColor? 278a966c04fSmrg * What about sharing systems like QDSS?). Beware: we have to treat 279a966c04fSmrg * DirectColor differently. 280a966c04fSmrg */ 281a966c04fSmrg 282a966c04fSmrg 283a966c04fSmrg long int red_closeness, green_closeness, blue_closeness; 284a966c04fSmrg int n; 285a966c04fSmrg Bool alloc_color; 286a966c04fSmrg 287a966c04fSmrg if (attributes && (attributes->valuemask & XpmCloseness)) 288a966c04fSmrg red_closeness = green_closeness = blue_closeness = 289a966c04fSmrg attributes->closeness; 290a966c04fSmrg else { 291a966c04fSmrg red_closeness = attributes->red_closeness; 292a966c04fSmrg green_closeness = attributes->green_closeness; 293a966c04fSmrg blue_closeness = attributes->blue_closeness; 294a966c04fSmrg } 295a966c04fSmrg if (attributes && (attributes->valuemask & XpmAllocCloseColors)) 296a966c04fSmrg alloc_color = attributes->alloc_close_colors; 297a966c04fSmrg else 298a966c04fSmrg alloc_color = True; 299a966c04fSmrg 300a966c04fSmrg /* 301a966c04fSmrg * We sort the colormap by closeness and try to allocate the color 302a966c04fSmrg * closest to the target. If the allocation of this close color fails, 303a966c04fSmrg * which almost never happens, then one of two scenarios is possible. 304a966c04fSmrg * Either the colormap must have changed (since the last close color 305a966c04fSmrg * allocation or possibly while we were sorting the colormap), or the 306a966c04fSmrg * color is allocated as Read/Write by some other client. (Note: X 307a966c04fSmrg * _should_ allow clients to check if a particular color is Read/Write, 308a966c04fSmrg * but it doesn't! :-( ). We cannot determine which of these scenarios 309a966c04fSmrg * occurred, so we try the next closest color, and so on, until no more 310a966c04fSmrg * colors are within closeness of the target. If we knew that the 311a966c04fSmrg * colormap had changed, we could skip this sequence. 31297cf2ee2Smrg * 313a966c04fSmrg * If _none_ of the colors within closeness of the target can be allocated, 314a966c04fSmrg * then we can finally be pretty sure that the colormap has actually 315a966c04fSmrg * changed. In this case we try to allocate the original color (again), 316a966c04fSmrg * then try the closecolor stuff (again)... 31797cf2ee2Smrg * 318a966c04fSmrg * In theory it would be possible for an infinite loop to occur if another 319a966c04fSmrg * process kept changing the colormap every time we sorted it, so we set 320a966c04fSmrg * a maximum on the number of iterations. After this many tries, we use 321a966c04fSmrg * XGrabServer() to ensure that the colormap remains unchanged. 32297cf2ee2Smrg * 323a966c04fSmrg * This approach gives particularly bad worst case performance - as many as 324a966c04fSmrg * <MaximumIterations> colormap reads and sorts may be needed, and as 325a966c04fSmrg * many as <MaximumIterations> * <ColormapSize> attempted allocations 326a966c04fSmrg * may fail. On an 8-bit system, this means as many as 3 colormap reads, 327a966c04fSmrg * 3 sorts and 768 failed allocations per execution of this code! 328a966c04fSmrg * Luckily, my experiments show that in general use in a typical 8-bit 329a966c04fSmrg * color environment only about 1 in every 10000 allocations fails to 330a966c04fSmrg * succeed in the fastest possible time. So virtually every time what 331a966c04fSmrg * actually happens is a single sort followed by a successful allocate. 332a966c04fSmrg * The very first allocation also costs a colormap read, but no further 333a966c04fSmrg * reads are usually necessary. 334a966c04fSmrg */ 335a966c04fSmrg 336a966c04fSmrg#define ITERATIONS 2 /* more than one is almost never 337a966c04fSmrg * necessary */ 338a966c04fSmrg 339a966c04fSmrg for (n = 0; n <= ITERATIONS; ++n) { 340a966c04fSmrg CloseColor *closenesses = 341a966c04fSmrg (CloseColor *) XpmCalloc(ncols, sizeof(CloseColor)); 342a966c04fSmrg int i, c; 343a966c04fSmrg 344a966c04fSmrg for (i = 0; i < ncols; ++i) { /* build & sort closenesses table */ 345a966c04fSmrg#define COLOR_FACTOR 3 346a966c04fSmrg#define BRIGHTNESS_FACTOR 1 347a966c04fSmrg 348a966c04fSmrg closenesses[i].cols_index = i; 349a966c04fSmrg closenesses[i].closeness = 3502f9f5fecSjoerg COLOR_FACTOR * (labs((long) col->red - (long) cols[i].red) 3512f9f5fecSjoerg + labs((long) col->green - (long) cols[i].green) 3522f9f5fecSjoerg + labs((long) col->blue - (long) cols[i].blue)) 3532f9f5fecSjoerg + BRIGHTNESS_FACTOR * labs(((long) col->red + 354a966c04fSmrg (long) col->green + 355a966c04fSmrg (long) col->blue) 356a966c04fSmrg - ((long) cols[i].red + 357a966c04fSmrg (long) cols[i].green + 358a966c04fSmrg (long) cols[i].blue)); 359a966c04fSmrg } 360a966c04fSmrg qsort(closenesses, ncols, sizeof(CloseColor), closeness_cmp); 361a966c04fSmrg 362a966c04fSmrg i = 0; 363a966c04fSmrg c = closenesses[i].cols_index; 364a966c04fSmrg while ((long) cols[c].red >= (long) col->red - red_closeness && 365a966c04fSmrg (long) cols[c].red <= (long) col->red + red_closeness && 366a966c04fSmrg (long) cols[c].green >= (long) col->green - green_closeness && 367a966c04fSmrg (long) cols[c].green <= (long) col->green + green_closeness && 368a966c04fSmrg (long) cols[c].blue >= (long) col->blue - blue_closeness && 369a966c04fSmrg (long) cols[c].blue <= (long) col->blue + blue_closeness) { 370a966c04fSmrg if (alloc_color) { 371a966c04fSmrg if ((*allocColor)(display, colormap, NULL, &cols[c], closure)){ 372a966c04fSmrg if (n == ITERATIONS) 373a966c04fSmrg XUngrabServer(display); 374a966c04fSmrg XpmFree(closenesses); 375a966c04fSmrg *image_pixel = cols[c].pixel; 376a966c04fSmrg *mask_pixel = 1; 377a966c04fSmrg alloc_pixels[(*nalloc_pixels)++] = cols[c].pixel; 378a966c04fSmrg return (0); 379a966c04fSmrg } else { 380a966c04fSmrg ++i; 381a966c04fSmrg if (i == ncols) 382a966c04fSmrg break; 383a966c04fSmrg c = closenesses[i].cols_index; 384a966c04fSmrg } 385a966c04fSmrg } else { 386a966c04fSmrg if (n == ITERATIONS) 387a966c04fSmrg XUngrabServer(display); 388a966c04fSmrg XpmFree(closenesses); 389a966c04fSmrg *image_pixel = cols[c].pixel; 390a966c04fSmrg *mask_pixel = 1; 391a966c04fSmrg return (0); 392a966c04fSmrg } 393a966c04fSmrg } 394a966c04fSmrg 395a966c04fSmrg /* Couldn't allocate _any_ of the close colors! */ 396a966c04fSmrg 397a966c04fSmrg if (n == ITERATIONS) 398a966c04fSmrg XUngrabServer(display); 399a966c04fSmrg XpmFree(closenesses); 400a966c04fSmrg 401a966c04fSmrg if (i == 0 || i == ncols) /* no color close enough or cannot */ 402a966c04fSmrg return (1); /* alloc any color (full of r/w's) */ 403a966c04fSmrg 404a966c04fSmrg if ((*allocColor)(display, colormap, NULL, col, closure)) { 405a966c04fSmrg *image_pixel = col->pixel; 406a966c04fSmrg *mask_pixel = 1; 407a966c04fSmrg alloc_pixels[(*nalloc_pixels)++] = col->pixel; 408a966c04fSmrg return (0); 409a966c04fSmrg } else { /* colormap has probably changed, so 410a966c04fSmrg * re-read... */ 411a966c04fSmrg if (n == ITERATIONS - 1) 412a966c04fSmrg XGrabServer(display); 413a966c04fSmrg 414a966c04fSmrg#if 0 415a966c04fSmrg if (visual->class == DirectColor) { 416a966c04fSmrg /* TODO */ 417a966c04fSmrg } else 418a966c04fSmrg#endif 419a966c04fSmrg XQueryColors(display, colormap, cols, ncols); 420a966c04fSmrg } 421a966c04fSmrg } 422a966c04fSmrg return (1); 423a966c04fSmrg} 424a966c04fSmrg 425a966c04fSmrg#define USE_CLOSECOLOR attributes && \ 426a966c04fSmrg(((attributes->valuemask & XpmCloseness) && attributes->closeness != 0) \ 427a966c04fSmrg || ((attributes->valuemask & XpmRGBCloseness) && \ 428a966c04fSmrg (attributes->red_closeness != 0 \ 429a966c04fSmrg || attributes->green_closeness != 0 \ 430a966c04fSmrg || attributes->blue_closeness != 0))) 431a966c04fSmrg 432a966c04fSmrg#else 433a966c04fSmrg /* FOR_MSW part */ 434a966c04fSmrg /* nothing to do here, the window system does it */ 435a966c04fSmrg#endif 436a966c04fSmrg 437a966c04fSmrg/* 438a966c04fSmrg * set the color pixel related to the given colorname, 439a966c04fSmrg * return 0 if success, 1 otherwise. 440a966c04fSmrg */ 441a966c04fSmrg 442a966c04fSmrgstatic int 4432e2dd055SmrgSetColor( 4442e2dd055Smrg Display *display, 4452e2dd055Smrg Colormap colormap, 4462e2dd055Smrg Visual *visual, 4472e2dd055Smrg char *colorname, 4482e2dd055Smrg unsigned int color_index, 4492e2dd055Smrg Pixel *image_pixel, 4502e2dd055Smrg Pixel *mask_pixel, 4512e2dd055Smrg unsigned int *mask_pixel_index, 4522e2dd055Smrg Pixel *alloc_pixels, 4532e2dd055Smrg unsigned int *nalloc_pixels, 4542e2dd055Smrg Pixel *used_pixels, 4552e2dd055Smrg unsigned int *nused_pixels, 4562e2dd055Smrg XpmAttributes *attributes, 4572e2dd055Smrg XColor *cols, 4582e2dd055Smrg int ncols, 4592e2dd055Smrg XpmAllocColorFunc allocColor, 4602e2dd055Smrg void *closure) 461a966c04fSmrg{ 462a966c04fSmrg XColor xcolor; 463a966c04fSmrg int status; 464a966c04fSmrg 465a966c04fSmrg if (xpmstrcasecmp(colorname, TRANSPARENT_COLOR)) { 466a966c04fSmrg status = (*allocColor)(display, colormap, colorname, &xcolor, closure); 467a966c04fSmrg if (status < 0) /* parse color failed */ 468a966c04fSmrg return (1); 469a966c04fSmrg 470a966c04fSmrg if (status == 0) { 471a966c04fSmrg#ifndef FOR_MSW 472a966c04fSmrg if (USE_CLOSECOLOR) 473a966c04fSmrg return (SetCloseColor(display, colormap, visual, &xcolor, 474a966c04fSmrg image_pixel, mask_pixel, 475a966c04fSmrg alloc_pixels, nalloc_pixels, 476a966c04fSmrg attributes, cols, ncols, 477a966c04fSmrg allocColor, closure)); 478a966c04fSmrg else 479a966c04fSmrg#endif /* ndef FOR_MSW */ 480a966c04fSmrg return (1); 481a966c04fSmrg } else 482a966c04fSmrg alloc_pixels[(*nalloc_pixels)++] = xcolor.pixel; 483a966c04fSmrg *image_pixel = xcolor.pixel; 484a966c04fSmrg#ifndef FOR_MSW 485a966c04fSmrg *mask_pixel = 1; 486a966c04fSmrg#else 487a966c04fSmrg *mask_pixel = RGB(0,0,0); 488a966c04fSmrg#endif 489a966c04fSmrg used_pixels[(*nused_pixels)++] = xcolor.pixel; 490a966c04fSmrg } else { 491a966c04fSmrg *image_pixel = 0; 492a966c04fSmrg#ifndef FOR_MSW 493a966c04fSmrg *mask_pixel = 0; 494a966c04fSmrg#else 495a966c04fSmrg *mask_pixel = RGB(255,255,255); 496a966c04fSmrg#endif 497a966c04fSmrg /* store the color table index */ 498a966c04fSmrg *mask_pixel_index = color_index; 499a966c04fSmrg } 500a966c04fSmrg return (0); 501a966c04fSmrg} 502a966c04fSmrg 503a966c04fSmrg 504a966c04fSmrgstatic int 5052e2dd055SmrgCreateColors( 5062e2dd055Smrg Display *display, 5072e2dd055Smrg XpmAttributes *attributes, 5082e2dd055Smrg XpmColor *colors, 5092e2dd055Smrg unsigned int ncolors, 5102e2dd055Smrg Pixel *image_pixels, 5112e2dd055Smrg Pixel *mask_pixels, 5122e2dd055Smrg unsigned int *mask_pixel_index, 5132e2dd055Smrg Pixel *alloc_pixels, 5142e2dd055Smrg unsigned int *nalloc_pixels, 5152e2dd055Smrg Pixel *used_pixels, 5162e2dd055Smrg unsigned int *nused_pixels) 517a966c04fSmrg{ 518a966c04fSmrg /* variables stored in the XpmAttributes structure */ 519a966c04fSmrg Visual *visual; 520a966c04fSmrg Colormap colormap; 521a966c04fSmrg XpmColorSymbol *colorsymbols = NULL; 522a966c04fSmrg unsigned int numsymbols; 523a966c04fSmrg XpmAllocColorFunc allocColor; 524a966c04fSmrg void *closure; 525a966c04fSmrg 526a966c04fSmrg char *colorname; 527a966c04fSmrg unsigned int color, key; 528a966c04fSmrg Bool pixel_defined; 529a966c04fSmrg XpmColorSymbol *symbol = NULL; 530a966c04fSmrg char **defaults; 531a966c04fSmrg int ErrorStatus = XpmSuccess; 532a966c04fSmrg char *s; 533a966c04fSmrg int default_index; 534a966c04fSmrg 535a966c04fSmrg XColor *cols = NULL; 536a966c04fSmrg unsigned int ncols = 0; 537a966c04fSmrg 538a966c04fSmrg /* 539a966c04fSmrg * retrieve information from the XpmAttributes 540a966c04fSmrg */ 541a966c04fSmrg if (attributes && attributes->valuemask & XpmColorSymbols) { 542a966c04fSmrg colorsymbols = attributes->colorsymbols; 543a966c04fSmrg numsymbols = attributes->numsymbols; 544a966c04fSmrg } else 545a966c04fSmrg numsymbols = 0; 546a966c04fSmrg 547a966c04fSmrg if (attributes && attributes->valuemask & XpmVisual) 548a966c04fSmrg visual = attributes->visual; 549a966c04fSmrg else 550a966c04fSmrg visual = XDefaultVisual(display, XDefaultScreen(display)); 551a966c04fSmrg 552a966c04fSmrg if (attributes && (attributes->valuemask & XpmColormap)) 553a966c04fSmrg colormap = attributes->colormap; 554a966c04fSmrg else 555a966c04fSmrg colormap = XDefaultColormap(display, XDefaultScreen(display)); 556a966c04fSmrg 557a966c04fSmrg if (attributes && (attributes->valuemask & XpmColorKey)) 558a966c04fSmrg key = attributes->color_key; 559a966c04fSmrg else 560a966c04fSmrg key = xpmVisualType(visual); 561a966c04fSmrg 562a966c04fSmrg if (attributes && (attributes->valuemask & XpmAllocColor)) 563a966c04fSmrg allocColor = attributes->alloc_color; 564a966c04fSmrg else 565a966c04fSmrg allocColor = AllocColor; 566a966c04fSmrg if (attributes && (attributes->valuemask & XpmColorClosure)) 567a966c04fSmrg closure = attributes->color_closure; 568a966c04fSmrg else 569a966c04fSmrg closure = NULL; 570a966c04fSmrg 571a966c04fSmrg#ifndef FOR_MSW 572a966c04fSmrg if (USE_CLOSECOLOR) { 573a966c04fSmrg /* originally from SetCloseColor */ 574a966c04fSmrg#if 0 575a966c04fSmrg if (visual->class == DirectColor) { 576a966c04fSmrg 577a966c04fSmrg /* 578a966c04fSmrg * TODO: Implement close colors for DirectColor visuals. This is 579a966c04fSmrg * difficult situation. Chances are that we will never get here, 580a966c04fSmrg * because any machine that supports DirectColor will probably 581a966c04fSmrg * also support TrueColor (and probably PseudoColor). Also, 582a966c04fSmrg * DirectColor colormaps can be very large, so looking for close 583a966c04fSmrg * colors may be too slow. 584a966c04fSmrg */ 585a966c04fSmrg } else { 586a966c04fSmrg#endif 587a966c04fSmrg unsigned int i; 588a966c04fSmrg 589a966c04fSmrg#ifndef AMIGA 590a966c04fSmrg ncols = visual->map_entries; 591a966c04fSmrg#else 592a966c04fSmrg ncols = colormap->Count; 593a966c04fSmrg#endif 594a966c04fSmrg cols = (XColor *) XpmCalloc(ncols, sizeof(XColor)); 595a966c04fSmrg for (i = 0; i < ncols; ++i) 596a966c04fSmrg cols[i].pixel = i; 597a966c04fSmrg XQueryColors(display, colormap, cols, ncols); 598a966c04fSmrg#if 0 599a966c04fSmrg } 600a966c04fSmrg#endif 601a966c04fSmrg } 602a966c04fSmrg#endif /* ndef FOR_MSW */ 603a966c04fSmrg 604a966c04fSmrg switch (key) { 605a966c04fSmrg case XPM_MONO: 606a966c04fSmrg default_index = 2; 607a966c04fSmrg break; 608a966c04fSmrg case XPM_GRAY4: 609a966c04fSmrg default_index = 3; 610a966c04fSmrg break; 611a966c04fSmrg case XPM_GRAY: 612a966c04fSmrg default_index = 4; 613a966c04fSmrg break; 614a966c04fSmrg case XPM_COLOR: 615a966c04fSmrg default: 616a966c04fSmrg default_index = 5; 617a966c04fSmrg break; 618a966c04fSmrg } 619a966c04fSmrg 620a966c04fSmrg for (color = 0; color < ncolors; color++, colors++, 621a966c04fSmrg image_pixels++, mask_pixels++) { 622a966c04fSmrg colorname = NULL; 623a966c04fSmrg pixel_defined = False; 624a966c04fSmrg defaults = (char **) colors; 625a966c04fSmrg 626a966c04fSmrg /* 627a966c04fSmrg * look for a defined symbol 628a966c04fSmrg */ 629a966c04fSmrg if (numsymbols) { 630a966c04fSmrg 631a966c04fSmrg unsigned int n; 632a966c04fSmrg 633a966c04fSmrg s = defaults[1]; 634a966c04fSmrg for (n = 0, symbol = colorsymbols; n < numsymbols; n++, symbol++) { 635a966c04fSmrg if (symbol->name && s && !strcmp(symbol->name, s)) 636a966c04fSmrg /* override name */ 637a966c04fSmrg break; 638a966c04fSmrg if (!symbol->name && symbol->value) { /* override value */ 639a966c04fSmrg int def_index = default_index; 640a966c04fSmrg 641a966c04fSmrg while (defaults[def_index] == NULL) /* find defined 642a966c04fSmrg * colorname */ 643a966c04fSmrg --def_index; 644a966c04fSmrg if (def_index < 2) {/* nothing towards mono, so try 645a966c04fSmrg * towards color */ 646a966c04fSmrg def_index = default_index + 1; 647a966c04fSmrg while (def_index <= 5 && defaults[def_index] == NULL) 648a966c04fSmrg ++def_index; 649a966c04fSmrg } 650d678aadfSmrg if (def_index >= 2 && def_index <= 5 && 651d678aadfSmrg defaults[def_index] != NULL && 652a966c04fSmrg !xpmstrcasecmp(symbol->value, defaults[def_index])) 653a966c04fSmrg break; 654a966c04fSmrg } 655a966c04fSmrg } 656a966c04fSmrg if (n != numsymbols) { 657a966c04fSmrg if (symbol->name && symbol->value) 658a966c04fSmrg colorname = symbol->value; 659a966c04fSmrg else 660a966c04fSmrg pixel_defined = True; 661a966c04fSmrg } 662a966c04fSmrg } 663a966c04fSmrg if (!pixel_defined) { /* pixel not given as symbol value */ 664a966c04fSmrg 665a966c04fSmrg unsigned int k; 666a966c04fSmrg 667a966c04fSmrg if (colorname) { /* colorname given as symbol value */ 668a966c04fSmrg if (!SetColor(display, colormap, visual, colorname, color, 669a966c04fSmrg image_pixels, mask_pixels, mask_pixel_index, 670a966c04fSmrg alloc_pixels, nalloc_pixels, used_pixels, 671a966c04fSmrg nused_pixels, attributes, cols, ncols, 672a966c04fSmrg allocColor, closure)) 673a966c04fSmrg pixel_defined = True; 674a966c04fSmrg else 675a966c04fSmrg ErrorStatus = XpmColorError; 676a966c04fSmrg } 677a966c04fSmrg k = key; 678a966c04fSmrg while (!pixel_defined && k > 1) { 679a966c04fSmrg if (defaults[k]) { 680a966c04fSmrg if (!SetColor(display, colormap, visual, defaults[k], 681a966c04fSmrg color, image_pixels, mask_pixels, 682a966c04fSmrg mask_pixel_index, alloc_pixels, 683a966c04fSmrg nalloc_pixels, used_pixels, nused_pixels, 684a966c04fSmrg attributes, cols, ncols, 685a966c04fSmrg allocColor, closure)) { 686a966c04fSmrg pixel_defined = True; 687a966c04fSmrg break; 688a966c04fSmrg } else 689a966c04fSmrg ErrorStatus = XpmColorError; 690a966c04fSmrg } 691a966c04fSmrg k--; 692a966c04fSmrg } 693a966c04fSmrg k = key + 1; 694a966c04fSmrg while (!pixel_defined && k < NKEYS + 1) { 695a966c04fSmrg if (defaults[k]) { 696a966c04fSmrg if (!SetColor(display, colormap, visual, defaults[k], 697a966c04fSmrg color, image_pixels, mask_pixels, 698a966c04fSmrg mask_pixel_index, alloc_pixels, 699a966c04fSmrg nalloc_pixels, used_pixels, nused_pixels, 700a966c04fSmrg attributes, cols, ncols, 701a966c04fSmrg allocColor, closure)) { 702a966c04fSmrg pixel_defined = True; 703a966c04fSmrg break; 704a966c04fSmrg } else 705a966c04fSmrg ErrorStatus = XpmColorError; 706a966c04fSmrg } 707a966c04fSmrg k++; 708a966c04fSmrg } 709a966c04fSmrg if (!pixel_defined) { 710a966c04fSmrg if (cols) 711a966c04fSmrg XpmFree(cols); 712a966c04fSmrg return (XpmColorFailed); 713a966c04fSmrg } 714a966c04fSmrg } else { 715a966c04fSmrg /* simply use the given pixel */ 716a966c04fSmrg *image_pixels = symbol->pixel; 717a966c04fSmrg /* the following makes the mask to be built even if none 718a966c04fSmrg is given a particular pixel */ 719a966c04fSmrg if (symbol->value 720a966c04fSmrg && !xpmstrcasecmp(symbol->value, TRANSPARENT_COLOR)) { 721a966c04fSmrg *mask_pixels = 0; 722a966c04fSmrg *mask_pixel_index = color; 723a966c04fSmrg } else 724a966c04fSmrg *mask_pixels = 1; 725a966c04fSmrg used_pixels[(*nused_pixels)++] = *image_pixels; 726a966c04fSmrg } 727a966c04fSmrg } 728a966c04fSmrg if (cols) 729a966c04fSmrg XpmFree(cols); 730a966c04fSmrg return (ErrorStatus); 731a966c04fSmrg} 732a966c04fSmrg 733a966c04fSmrg 734a966c04fSmrg/* default FreeColors function, simply call XFreeColors */ 735a966c04fSmrgstatic int 7362e2dd055SmrgFreeColors( 7372e2dd055Smrg Display *display, 7382e2dd055Smrg Colormap colormap, 7392e2dd055Smrg Pixel *pixels, 7402e2dd055Smrg int n, 7412e2dd055Smrg void *closure) /* not used */ 742a966c04fSmrg{ 743a966c04fSmrg return XFreeColors(display, colormap, pixels, n, 0); 744a966c04fSmrg} 745a966c04fSmrg 746a966c04fSmrg 747a966c04fSmrg/* function call in case of error */ 748a966c04fSmrg 749a966c04fSmrg#undef RETURN 750a966c04fSmrg#define RETURN(status) \ 751a966c04fSmrgdo \ 752a966c04fSmrg{ \ 753a966c04fSmrg ErrorStatus = status; \ 754a966c04fSmrg goto error; \ 755a966c04fSmrg} while(0) 756a966c04fSmrg 757a966c04fSmrgint 7582e2dd055SmrgXpmCreateImageFromXpmImage( 7592e2dd055Smrg Display *display, 7602e2dd055Smrg XpmImage *image, 7612e2dd055Smrg XImage **image_return, 7622e2dd055Smrg XImage **shapeimage_return, 7632e2dd055Smrg XpmAttributes *attributes) 764a966c04fSmrg{ 765a966c04fSmrg /* variables stored in the XpmAttributes structure */ 766a966c04fSmrg Visual *visual; 767a966c04fSmrg Colormap colormap; 768a966c04fSmrg unsigned int depth; 769a966c04fSmrg int bitmap_format; 770a966c04fSmrg XpmFreeColorsFunc freeColors; 771a966c04fSmrg 772a966c04fSmrg /* variables to return */ 773a966c04fSmrg XImage *ximage = NULL; 774a966c04fSmrg XImage *shapeimage = NULL; 775a966c04fSmrg unsigned int mask_pixel_index = XpmUndefPixel; 776a966c04fSmrg int ErrorStatus; 777a966c04fSmrg 778a966c04fSmrg /* calculation variables */ 779a966c04fSmrg Pixel *image_pixels = NULL; 780a966c04fSmrg Pixel *mask_pixels = NULL; 781a966c04fSmrg Pixel *alloc_pixels = NULL; 782a966c04fSmrg Pixel *used_pixels = NULL; 783a966c04fSmrg unsigned int nalloc_pixels = 0; 784a966c04fSmrg unsigned int nused_pixels = 0; 785a966c04fSmrg 786a966c04fSmrg /* initialize return values */ 787a966c04fSmrg if (image_return) 788a966c04fSmrg *image_return = NULL; 789a966c04fSmrg if (shapeimage_return) 790a966c04fSmrg *shapeimage_return = NULL; 791a966c04fSmrg 792a966c04fSmrg /* retrieve information from the XpmAttributes */ 793a966c04fSmrg if (attributes && (attributes->valuemask & XpmVisual)) 794a966c04fSmrg visual = attributes->visual; 795a966c04fSmrg else 796a966c04fSmrg visual = XDefaultVisual(display, XDefaultScreen(display)); 797a966c04fSmrg 798a966c04fSmrg if (attributes && (attributes->valuemask & XpmColormap)) 799a966c04fSmrg colormap = attributes->colormap; 800a966c04fSmrg else 801a966c04fSmrg colormap = XDefaultColormap(display, XDefaultScreen(display)); 802a966c04fSmrg 803a966c04fSmrg if (attributes && (attributes->valuemask & XpmDepth)) 804a966c04fSmrg depth = attributes->depth; 805a966c04fSmrg else 806a966c04fSmrg depth = XDefaultDepth(display, XDefaultScreen(display)); 807a966c04fSmrg 808a966c04fSmrg if (attributes && (attributes->valuemask & XpmBitmapFormat)) 809a966c04fSmrg bitmap_format = attributes->bitmap_format; 810a966c04fSmrg else 811a966c04fSmrg bitmap_format = ZPixmap; 812a966c04fSmrg 813a966c04fSmrg if (attributes && (attributes->valuemask & XpmFreeColors)) 814a966c04fSmrg freeColors = attributes->free_colors; 815a966c04fSmrg else 816a966c04fSmrg freeColors = FreeColors; 817a966c04fSmrg 818a966c04fSmrg ErrorStatus = XpmSuccess; 819a966c04fSmrg 82097cf2ee2Smrg if (image->ncolors >= UINT_MAX / sizeof(Pixel)) 821a966c04fSmrg return (XpmNoMemory); 822a966c04fSmrg 823a966c04fSmrg /* malloc pixels index tables */ 824a966c04fSmrg image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); 825a966c04fSmrg if (!image_pixels) 826a966c04fSmrg return (XpmNoMemory); 827a966c04fSmrg 828a966c04fSmrg mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); 829a966c04fSmrg if (!mask_pixels) 830a966c04fSmrg RETURN(XpmNoMemory); 831a966c04fSmrg 832a966c04fSmrg /* maximum of allocated pixels will be the number of colors */ 833a966c04fSmrg alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); 834a966c04fSmrg if (!alloc_pixels) 835a966c04fSmrg RETURN(XpmNoMemory); 836a966c04fSmrg 837a966c04fSmrg /* maximum of allocated pixels will be the number of colors */ 838a966c04fSmrg used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); 839a966c04fSmrg if (!used_pixels) 840a966c04fSmrg RETURN(XpmNoMemory); 841a966c04fSmrg 842a966c04fSmrg /* get pixel colors, store them in index tables */ 843a966c04fSmrg ErrorStatus = CreateColors(display, attributes, image->colorTable, 844a966c04fSmrg image->ncolors, image_pixels, mask_pixels, 845a966c04fSmrg &mask_pixel_index, alloc_pixels, &nalloc_pixels, 846a966c04fSmrg used_pixels, &nused_pixels); 847a966c04fSmrg 848a966c04fSmrg if (ErrorStatus != XpmSuccess 849a966c04fSmrg && (ErrorStatus < 0 || (attributes 850a966c04fSmrg && (attributes->valuemask & XpmExactColors) 851a966c04fSmrg && attributes->exactColors))) 852a966c04fSmrg RETURN(ErrorStatus); 853a966c04fSmrg 854a966c04fSmrg /* create the ximage */ 855a966c04fSmrg if (image_return) { 856a966c04fSmrg ErrorStatus = CreateXImage(display, visual, depth, 857a966c04fSmrg (depth == 1 ? bitmap_format : ZPixmap), 858a966c04fSmrg image->width, image->height, &ximage); 859a966c04fSmrg if (ErrorStatus != XpmSuccess) 860a966c04fSmrg RETURN(ErrorStatus); 861a966c04fSmrg 862a966c04fSmrg#ifndef FOR_MSW 863a966c04fSmrg# ifndef AMIGA 864a966c04fSmrg 865a966c04fSmrg /* 866a966c04fSmrg * set the ximage data using optimized functions for ZPixmap 867a966c04fSmrg */ 868a966c04fSmrg 869a966c04fSmrg if (ximage->bits_per_pixel == 8) 870a966c04fSmrg PutImagePixels8(ximage, image->width, image->height, 871a966c04fSmrg image->data, image_pixels); 872a966c04fSmrg else if (((ximage->bits_per_pixel | ximage->depth) == 1) && 873a966c04fSmrg (ximage->byte_order == ximage->bitmap_bit_order)) 874a966c04fSmrg PutImagePixels1(ximage, image->width, image->height, 875a966c04fSmrg image->data, image_pixels); 876a966c04fSmrg else if (ximage->bits_per_pixel == 16) 877a966c04fSmrg PutImagePixels16(ximage, image->width, image->height, 878a966c04fSmrg image->data, image_pixels); 879a966c04fSmrg else if (ximage->bits_per_pixel == 32) 880a966c04fSmrg PutImagePixels32(ximage, image->width, image->height, 881a966c04fSmrg image->data, image_pixels); 882a966c04fSmrg else 883a966c04fSmrg PutImagePixels(ximage, image->width, image->height, 884a966c04fSmrg image->data, image_pixels); 885a966c04fSmrg# else /* AMIGA */ 886a966c04fSmrg APutImagePixels(ximage, image->width, image->height, 887a966c04fSmrg image->data, image_pixels); 888a966c04fSmrg# endif 889a966c04fSmrg#else /* FOR_MSW */ 890a966c04fSmrg MSWPutImagePixels(display, ximage, image->width, image->height, 891a966c04fSmrg image->data, image_pixels); 892a966c04fSmrg#endif 893a966c04fSmrg } 894a966c04fSmrg /* create the shape mask image */ 895a966c04fSmrg if (mask_pixel_index != XpmUndefPixel && shapeimage_return) { 896a966c04fSmrg ErrorStatus = CreateXImage(display, visual, 1, bitmap_format, 897a966c04fSmrg image->width, image->height, &shapeimage); 898a966c04fSmrg if (ErrorStatus != XpmSuccess) 899a966c04fSmrg RETURN(ErrorStatus); 900a966c04fSmrg 901a966c04fSmrg#ifndef FOR_MSW 902a966c04fSmrg# ifndef AMIGA 903a966c04fSmrg PutImagePixels1(shapeimage, image->width, image->height, 904a966c04fSmrg image->data, mask_pixels); 905a966c04fSmrg# else /* AMIGA */ 906a966c04fSmrg APutImagePixels(shapeimage, image->width, image->height, 907a966c04fSmrg image->data, mask_pixels); 908a966c04fSmrg# endif 909a966c04fSmrg#else /* FOR_MSW */ 910a966c04fSmrg MSWPutImagePixels(display, shapeimage, image->width, image->height, 911a966c04fSmrg image->data, mask_pixels); 912a966c04fSmrg#endif 913a966c04fSmrg 914a966c04fSmrg } 915a966c04fSmrg XpmFree(image_pixels); 916a966c04fSmrg XpmFree(mask_pixels); 917a966c04fSmrg 918a966c04fSmrg /* if requested return used pixels in the XpmAttributes structure */ 919a966c04fSmrg if (attributes && (attributes->valuemask & XpmReturnPixels || 920a966c04fSmrg/* 3.2 backward compatibility code */ 921a966c04fSmrg attributes->valuemask & XpmReturnInfos)) { 922a966c04fSmrg/* end 3.2 bc */ 923a966c04fSmrg attributes->pixels = used_pixels; 924a966c04fSmrg attributes->npixels = nused_pixels; 925a966c04fSmrg attributes->mask_pixel = mask_pixel_index; 926a966c04fSmrg } else 927a966c04fSmrg XpmFree(used_pixels); 928a966c04fSmrg 929a966c04fSmrg /* if requested return alloc'ed pixels in the XpmAttributes structure */ 930a966c04fSmrg if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) { 931a966c04fSmrg attributes->alloc_pixels = alloc_pixels; 932a966c04fSmrg attributes->nalloc_pixels = nalloc_pixels; 933a966c04fSmrg } else 934a966c04fSmrg XpmFree(alloc_pixels); 935a966c04fSmrg 936a966c04fSmrg /* return created images */ 937a966c04fSmrg if (image_return) 938a966c04fSmrg *image_return = ximage; 939a966c04fSmrg if (shapeimage_return) 940a966c04fSmrg *shapeimage_return = shapeimage; 941a966c04fSmrg 942a966c04fSmrg return (ErrorStatus); 943a966c04fSmrg 944a966c04fSmrg/* exit point in case of error, free only locally allocated variables */ 945a966c04fSmrgerror: 946a966c04fSmrg if (ximage) 947a966c04fSmrg XDestroyImage(ximage); 948a966c04fSmrg if (shapeimage) 949a966c04fSmrg XDestroyImage(shapeimage); 950a966c04fSmrg if (image_pixels) 951a966c04fSmrg XpmFree(image_pixels); 952a966c04fSmrg if (mask_pixels) 953a966c04fSmrg XpmFree(mask_pixels); 954a966c04fSmrg if (nalloc_pixels) 955a966c04fSmrg (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL); 956a966c04fSmrg if (alloc_pixels) 957a966c04fSmrg XpmFree(alloc_pixels); 958a966c04fSmrg if (used_pixels) 959a966c04fSmrg XpmFree(used_pixels); 960a966c04fSmrg 961a966c04fSmrg return (ErrorStatus); 962a966c04fSmrg} 963a966c04fSmrg 964a966c04fSmrg 965a966c04fSmrg/* 966a966c04fSmrg * Create an XImage with its data 967a966c04fSmrg */ 968a966c04fSmrgstatic int 9692e2dd055SmrgCreateXImage( 9702e2dd055Smrg Display *display, 9712e2dd055Smrg Visual *visual, 9722e2dd055Smrg unsigned int depth, 9732e2dd055Smrg int format, 9742e2dd055Smrg unsigned int width, 9752e2dd055Smrg unsigned int height, 9762e2dd055Smrg XImage **image_return) 977a966c04fSmrg{ 978a966c04fSmrg int bitmap_pad; 979a966c04fSmrg 980a966c04fSmrg /* first get bitmap_pad */ 981a966c04fSmrg if (depth > 16) 982a966c04fSmrg bitmap_pad = 32; 983a966c04fSmrg else if (depth > 8) 984a966c04fSmrg bitmap_pad = 16; 985a966c04fSmrg else 986a966c04fSmrg bitmap_pad = 8; 987a966c04fSmrg 988a966c04fSmrg /* then create the XImage with data = NULL and bytes_per_line = 0 */ 989a966c04fSmrg *image_return = XCreateImage(display, visual, depth, format, 0, 0, 990a966c04fSmrg width, height, bitmap_pad, 0); 991a966c04fSmrg if (!*image_return) 992a966c04fSmrg return (XpmNoMemory); 993a966c04fSmrg 994a966c04fSmrg#if !defined(FOR_MSW) && !defined(AMIGA) 995a966c04fSmrg if (height != 0 && (*image_return)->bytes_per_line >= INT_MAX / height) { 996a966c04fSmrg XDestroyImage(*image_return); 997c378da89Smrg *image_return = NULL; 998a966c04fSmrg return XpmNoMemory; 999a966c04fSmrg } 10004e08afa9Smrg if (width != 0 && (*image_return)->bits_per_pixel >= INT_MAX / width) { 10014e08afa9Smrg XDestroyImage(*image_return); 10024e08afa9Smrg *image_return = NULL; 10034e08afa9Smrg return XpmNoMemory; 10044e08afa9Smrg } 1005a966c04fSmrg /* now that bytes_per_line must have been set properly alloc data */ 1006c378da89Smrg if((*image_return)->bytes_per_line == 0 || height == 0) { 1007c378da89Smrg XDestroyImage(*image_return); 1008c378da89Smrg *image_return = NULL; 1009a966c04fSmrg return XpmNoMemory; 1010c378da89Smrg } 1011a966c04fSmrg (*image_return)->data = 1012a966c04fSmrg (char *) XpmMalloc((*image_return)->bytes_per_line * height); 1013a966c04fSmrg 1014a966c04fSmrg if (!(*image_return)->data) { 1015a966c04fSmrg XDestroyImage(*image_return); 1016a966c04fSmrg *image_return = NULL; 1017a966c04fSmrg return (XpmNoMemory); 1018a966c04fSmrg } 1019a966c04fSmrg#else 1020a966c04fSmrg /* under FOR_MSW and AMIGA XCreateImage has done it all */ 1021a966c04fSmrg#endif 1022a966c04fSmrg return (XpmSuccess); 1023a966c04fSmrg} 1024a966c04fSmrg 1025a966c04fSmrg#ifndef FOR_MSW 1026a966c04fSmrg# ifndef AMIGA 1027a966c04fSmrg/* 1028a966c04fSmrg * The functions below are written from X11R5 MIT's code (XImUtil.c) 1029a966c04fSmrg * 1030a966c04fSmrg * The idea is to have faster functions than the standard XPutPixel function 1031a966c04fSmrg * to build the image data. Indeed we can speed up things by suppressing tests 1032a966c04fSmrg * performed for each pixel. We do the same tests but at the image level. 1033a966c04fSmrg * We also assume that we use only ZPixmap images with null offsets. 1034a966c04fSmrg */ 1035a966c04fSmrg 1036a966c04fSmrgLFUNC(_putbits, void, (register char *src, int dstoffset, 1037a966c04fSmrg register int numbits, register char *dst)); 1038a966c04fSmrg 1039a966c04fSmrgLFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register unsigned int nb)); 1040a966c04fSmrg 104197cf2ee2Smrgstatic unsigned char const _reverse_byte[0x100] = { 1042a966c04fSmrg 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 1043a966c04fSmrg 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 1044a966c04fSmrg 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 1045a966c04fSmrg 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 1046a966c04fSmrg 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 1047a966c04fSmrg 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 1048a966c04fSmrg 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 1049a966c04fSmrg 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 1050a966c04fSmrg 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 1051a966c04fSmrg 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 1052a966c04fSmrg 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 1053a966c04fSmrg 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 1054a966c04fSmrg 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 1055a966c04fSmrg 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 1056a966c04fSmrg 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 1057a966c04fSmrg 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 1058a966c04fSmrg 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 1059a966c04fSmrg 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 1060a966c04fSmrg 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 1061a966c04fSmrg 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 1062a966c04fSmrg 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 1063a966c04fSmrg 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 1064a966c04fSmrg 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 1065a966c04fSmrg 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 1066a966c04fSmrg 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 1067a966c04fSmrg 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 1068a966c04fSmrg 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 1069a966c04fSmrg 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 1070a966c04fSmrg 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 1071a966c04fSmrg 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 1072a966c04fSmrg 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 1073a966c04fSmrg 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff 1074a966c04fSmrg}; 1075a966c04fSmrg 1076a966c04fSmrgstatic int 10772e2dd055Smrg_XReverse_Bytes( 10782e2dd055Smrg register unsigned char *bpt, 10792e2dd055Smrg register unsigned int nb) 1080a966c04fSmrg{ 1081a966c04fSmrg do { 1082a966c04fSmrg *bpt = _reverse_byte[*bpt]; 1083a966c04fSmrg bpt++; 1084a966c04fSmrg } while (--nb > 0); /* is nb user-controled? */ 1085a966c04fSmrg return 0; 1086a966c04fSmrg} 1087a966c04fSmrg 1088a966c04fSmrg 1089a966c04fSmrgvoid 10902e2dd055Smrgxpm_xynormalizeimagebits( 10912e2dd055Smrg register unsigned char *bp, 10922e2dd055Smrg register XImage *img) 1093a966c04fSmrg{ 1094a966c04fSmrg register unsigned char c; 1095a966c04fSmrg 1096a966c04fSmrg if (img->byte_order != img->bitmap_bit_order) { 1097a966c04fSmrg switch (img->bitmap_unit) { 1098a966c04fSmrg 1099a966c04fSmrg case 16: 1100a966c04fSmrg c = *bp; 1101a966c04fSmrg *bp = *(bp + 1); 1102a966c04fSmrg *(bp + 1) = c; 1103a966c04fSmrg break; 1104a966c04fSmrg 1105a966c04fSmrg case 32: 1106a966c04fSmrg c = *(bp + 3); 1107a966c04fSmrg *(bp + 3) = *bp; 1108a966c04fSmrg *bp = c; 1109a966c04fSmrg c = *(bp + 2); 1110a966c04fSmrg *(bp + 2) = *(bp + 1); 1111a966c04fSmrg *(bp + 1) = c; 1112a966c04fSmrg break; 1113a966c04fSmrg } 1114a966c04fSmrg } 1115a966c04fSmrg if (img->bitmap_bit_order == MSBFirst) 1116a966c04fSmrg _XReverse_Bytes(bp, img->bitmap_unit >> 3); 1117a966c04fSmrg} 1118a966c04fSmrg 1119a966c04fSmrgvoid 11202e2dd055Smrgxpm_znormalizeimagebits( 11212e2dd055Smrg register unsigned char *bp, 11222e2dd055Smrg register XImage *img) 1123a966c04fSmrg{ 1124a966c04fSmrg register unsigned char c; 1125a966c04fSmrg 1126a966c04fSmrg switch (img->bits_per_pixel) { 1127a966c04fSmrg 1128a966c04fSmrg case 2: 1129a966c04fSmrg _XReverse_Bytes(bp, 1); 1130a966c04fSmrg break; 1131a966c04fSmrg 1132a966c04fSmrg case 4: 1133a966c04fSmrg *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF); 1134a966c04fSmrg break; 1135a966c04fSmrg 1136a966c04fSmrg case 16: 1137a966c04fSmrg c = *bp; 1138a966c04fSmrg *bp = *(bp + 1); 1139a966c04fSmrg *(bp + 1) = c; 1140a966c04fSmrg break; 1141a966c04fSmrg 1142a966c04fSmrg case 24: 1143a966c04fSmrg c = *(bp + 2); 1144a966c04fSmrg *(bp + 2) = *bp; 1145a966c04fSmrg *bp = c; 1146a966c04fSmrg break; 1147a966c04fSmrg 1148a966c04fSmrg case 32: 1149a966c04fSmrg c = *(bp + 3); 1150a966c04fSmrg *(bp + 3) = *bp; 1151a966c04fSmrg *bp = c; 1152a966c04fSmrg c = *(bp + 2); 1153a966c04fSmrg *(bp + 2) = *(bp + 1); 1154a966c04fSmrg *(bp + 1) = c; 1155a966c04fSmrg break; 1156a966c04fSmrg } 1157a966c04fSmrg} 1158a966c04fSmrg 115997cf2ee2Smrgstatic unsigned char const _lomask[0x09] = { 1160a966c04fSmrg0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; 116197cf2ee2Smrgstatic unsigned char const _himask[0x09] = { 1162a966c04fSmrg0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00}; 1163a966c04fSmrg 1164a966c04fSmrgstatic void 11652e2dd055Smrg_putbits( 11662e2dd055Smrg register char *src, /* address of source bit string */ 11672e2dd055Smrg int dstoffset, /* bit offset into destination; 1168a966c04fSmrg * range is 0-31 */ 11692e2dd055Smrg register int numbits, /* number of bits to copy to 1170a966c04fSmrg * destination */ 11712e2dd055Smrg register char *dst) /* address of destination bit string */ 1172a966c04fSmrg{ 1173a966c04fSmrg register unsigned char chlo, chhi; 1174a966c04fSmrg int hibits; 1175a966c04fSmrg 1176a966c04fSmrg dst = dst + (dstoffset >> 3); 1177a966c04fSmrg dstoffset = dstoffset & 7; 1178a966c04fSmrg hibits = 8 - dstoffset; 1179a966c04fSmrg chlo = *dst & _lomask[dstoffset]; 1180a966c04fSmrg for (;;) { 1181a966c04fSmrg chhi = (*src << dstoffset) & _himask[dstoffset]; 1182a966c04fSmrg if (numbits <= hibits) { 1183a966c04fSmrg chhi = chhi & _lomask[dstoffset + numbits]; 1184a966c04fSmrg *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi; 1185a966c04fSmrg break; 1186a966c04fSmrg } 1187a966c04fSmrg *dst = chhi | chlo; 1188a966c04fSmrg dst++; 1189a966c04fSmrg numbits = numbits - hibits; 1190a966c04fSmrg chlo = (unsigned char) (*src & _himask[hibits]) >> hibits; 1191a966c04fSmrg src++; 1192a966c04fSmrg if (numbits <= dstoffset) { 1193a966c04fSmrg chlo = chlo & _lomask[numbits]; 1194a966c04fSmrg *dst = (*dst & _himask[numbits]) | chlo; 1195a966c04fSmrg break; 1196a966c04fSmrg } 1197a966c04fSmrg numbits = numbits - dstoffset; 1198a966c04fSmrg } 1199a966c04fSmrg} 1200a966c04fSmrg 1201a966c04fSmrg/* 1202a966c04fSmrg * Default method to write pixels into a Z image data structure. 1203a966c04fSmrg * The algorithm used is: 1204a966c04fSmrg * 1205a966c04fSmrg * copy the destination bitmap_unit or Zpixel to temp 1206a966c04fSmrg * normalize temp if needed 1207a966c04fSmrg * copy the pixel bits into the temp 1208a966c04fSmrg * renormalize temp if needed 1209a966c04fSmrg * copy the temp back into the destination image data 1210a966c04fSmrg */ 1211a966c04fSmrg 1212a966c04fSmrgstatic void 12132e2dd055SmrgPutImagePixels( 12142e2dd055Smrg XImage *image, 12152e2dd055Smrg unsigned int width, 12162e2dd055Smrg unsigned int height, 12172e2dd055Smrg unsigned int *pixelindex, 12182e2dd055Smrg Pixel *pixels) 1219a966c04fSmrg{ 1220a966c04fSmrg register char *src; 1221a966c04fSmrg register char *dst; 1222a966c04fSmrg register unsigned int *iptr; 1223a966c04fSmrg register unsigned int x, y; 1224a966c04fSmrg register char *data; 1225a966c04fSmrg Pixel pixel, px; 1226a966c04fSmrg int nbytes, depth, ibu, ibpp, i; 1227a966c04fSmrg 1228a966c04fSmrg data = image->data; 1229a966c04fSmrg iptr = pixelindex; 1230a966c04fSmrg depth = image->depth; 1231a966c04fSmrg if (depth == 1) { 1232a966c04fSmrg ibu = image->bitmap_unit; 1233a966c04fSmrg for (y = 0; y < height; y++) /* how can we trust height */ 1234a966c04fSmrg for (x = 0; x < width; x++, iptr++) { /* how can we trust width */ 1235a966c04fSmrg pixel = pixels[*iptr]; 1236a966c04fSmrg for (i = 0, px = pixel; i < sizeof(unsigned long); 1237a966c04fSmrg i++, px >>= 8) 1238a966c04fSmrg ((unsigned char *) &pixel)[i] = px; 1239a966c04fSmrg src = &data[XYINDEX(x, y, image)]; 1240a966c04fSmrg dst = (char *) &px; 1241a966c04fSmrg px = 0; 1242a966c04fSmrg nbytes = ibu >> 3; 1243a966c04fSmrg for (i = nbytes; --i >= 0;) 1244a966c04fSmrg *dst++ = *src++; 1245a966c04fSmrg XYNORMALIZE(&px, image); 1246a966c04fSmrg _putbits((char *) &pixel, (x % ibu), 1, (char *) &px); 1247a966c04fSmrg XYNORMALIZE(&px, image); 1248a966c04fSmrg src = (char *) &px; 1249a966c04fSmrg dst = &data[XYINDEX(x, y, image)]; 1250a966c04fSmrg for (i = nbytes; --i >= 0;) 1251a966c04fSmrg *dst++ = *src++; 1252a966c04fSmrg } 1253a966c04fSmrg } else { 1254a966c04fSmrg ibpp = image->bits_per_pixel; 1255a966c04fSmrg for (y = 0; y < height; y++) 1256a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 1257a966c04fSmrg pixel = pixels[*iptr]; 1258a966c04fSmrg if (depth == 4) 1259a966c04fSmrg pixel &= 0xf; 1260a966c04fSmrg for (i = 0, px = pixel; i < sizeof(unsigned long); i++, 1261a966c04fSmrg px >>= 8) 1262a966c04fSmrg ((unsigned char *) &pixel)[i] = px; 1263a966c04fSmrg src = &data[ZINDEX(x, y, image)]; 1264a966c04fSmrg dst = (char *) &px; 1265a966c04fSmrg px = 0; 1266a966c04fSmrg nbytes = (ibpp + 7) >> 3; 1267a966c04fSmrg for (i = nbytes; --i >= 0;) 1268a966c04fSmrg *dst++ = *src++; 1269a966c04fSmrg ZNORMALIZE(&px, image); 1270a966c04fSmrg _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px); 1271a966c04fSmrg ZNORMALIZE(&px, image); 1272a966c04fSmrg src = (char *) &px; 1273a966c04fSmrg dst = &data[ZINDEX(x, y, image)]; 1274a966c04fSmrg for (i = nbytes; --i >= 0;) 1275a966c04fSmrg *dst++ = *src++; 1276a966c04fSmrg } 1277a966c04fSmrg } 1278a966c04fSmrg} 1279a966c04fSmrg 1280a966c04fSmrg/* 1281a966c04fSmrg * write pixels into a 32-bits Z image data structure 1282a966c04fSmrg */ 1283a966c04fSmrg 1284a966c04fSmrg#if !defined(WORD64) && !defined(LONG64) 1285a966c04fSmrg/* this item is static but deterministic so let it slide; doesn't 1286a966c04fSmrg * hurt re-entrancy of this library. Note if it is actually const then would 1287a966c04fSmrg * be OK under rules of ANSI-C but probably not C++ which may not 1288a966c04fSmrg * want to allocate space for it. 1289a966c04fSmrg */ 1290a966c04fSmrgstatic unsigned long byteorderpixel = MSBFirst << 24; 1291a966c04fSmrg 1292a966c04fSmrg#endif 1293a966c04fSmrg 1294a966c04fSmrg/* 1295a966c04fSmrg WITHOUT_SPEEDUPS is a flag to be turned on if you wish to use the original 1296a966c04fSmrg 3.2e code - by default you get the speeded-up version. 1297a966c04fSmrg*/ 1298a966c04fSmrg 1299a966c04fSmrgstatic void 13002e2dd055SmrgPutImagePixels32( 13012e2dd055Smrg XImage *image, 13022e2dd055Smrg unsigned int width, 13032e2dd055Smrg unsigned int height, 13042e2dd055Smrg unsigned int *pixelindex, 13052e2dd055Smrg Pixel *pixels) 1306a966c04fSmrg{ 1307a966c04fSmrg unsigned char *data; 1308a966c04fSmrg unsigned int *iptr; 1309a966c04fSmrg unsigned int y; 1310a966c04fSmrg Pixel pixel; 1311a966c04fSmrg 1312a966c04fSmrg#ifdef WITHOUT_SPEEDUPS 1313a966c04fSmrg 1314a966c04fSmrg unsigned int x; 1315a966c04fSmrg unsigned char *addr; 1316a966c04fSmrg 1317a966c04fSmrg data = (unsigned char *) image->data; 1318a966c04fSmrg iptr = pixelindex; 1319a966c04fSmrg#if !defined(WORD64) && !defined(LONG64) 1320a966c04fSmrg if (*((char *) &byteorderpixel) == image->byte_order) { 1321a966c04fSmrg for (y = 0; y < height; y++) 1322a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 1323a966c04fSmrg addr = &data[ZINDEX32(x, y, image)]; 1324a966c04fSmrg *((unsigned long *) addr) = pixels[*iptr]; 1325a966c04fSmrg } 1326a966c04fSmrg } else 1327a966c04fSmrg#endif 1328a966c04fSmrg if (image->byte_order == MSBFirst) 1329a966c04fSmrg for (y = 0; y < height; y++) 1330a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 1331a966c04fSmrg addr = &data[ZINDEX32(x, y, image)]; 1332a966c04fSmrg pixel = pixels[*iptr]; 1333a966c04fSmrg addr[0] = pixel >> 24; 1334a966c04fSmrg addr[1] = pixel >> 16; 1335a966c04fSmrg addr[2] = pixel >> 8; 1336a966c04fSmrg addr[3] = pixel; 1337a966c04fSmrg } 1338a966c04fSmrg else 1339a966c04fSmrg for (y = 0; y < height; y++) 1340a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 1341a966c04fSmrg addr = &data[ZINDEX32(x, y, image)]; 1342a966c04fSmrg pixel = pixels[*iptr]; 1343a966c04fSmrg addr[0] = pixel; 1344a966c04fSmrg addr[1] = pixel >> 8; 1345a966c04fSmrg addr[2] = pixel >> 16; 1346a966c04fSmrg addr[3] = pixel >> 24; 1347a966c04fSmrg } 1348a966c04fSmrg 1349a966c04fSmrg#else /* WITHOUT_SPEEDUPS */ 1350a966c04fSmrg 1351a966c04fSmrg unsigned int bpl = image->bytes_per_line; 1352a966c04fSmrg unsigned char *data_ptr, *max_data; 1353a966c04fSmrg 1354a966c04fSmrg data = (unsigned char *) image->data; 1355a966c04fSmrg iptr = pixelindex; 1356a966c04fSmrg#if !defined(WORD64) && !defined(LONG64) 1357a966c04fSmrg if (*((char *) &byteorderpixel) == image->byte_order) { 1358a966c04fSmrg for (y = 0; y < height; y++) { 1359a966c04fSmrg data_ptr = data; 1360a966c04fSmrg max_data = data_ptr + (width << 2); 1361a966c04fSmrg 1362a966c04fSmrg while (data_ptr < max_data) { 1363a966c04fSmrg *((unsigned long *) data_ptr) = pixels[*(iptr++)]; 1364a966c04fSmrg data_ptr += (1 << 2); 1365a966c04fSmrg } 1366a966c04fSmrg data += bpl; 1367a966c04fSmrg } 1368a966c04fSmrg } else 1369a966c04fSmrg#endif 1370a966c04fSmrg if (image->byte_order == MSBFirst) 1371a966c04fSmrg for (y = 0; y < height; y++) { 1372a966c04fSmrg data_ptr = data; 1373a966c04fSmrg max_data = data_ptr + (width << 2); 1374a966c04fSmrg 1375a966c04fSmrg while (data_ptr < max_data) { 1376a966c04fSmrg pixel = pixels[*(iptr++)]; 1377a966c04fSmrg 1378a966c04fSmrg *data_ptr++ = pixel >> 24; 1379a966c04fSmrg *data_ptr++ = pixel >> 16; 1380a966c04fSmrg *data_ptr++ = pixel >> 8; 1381a966c04fSmrg *data_ptr++ = pixel; 1382a966c04fSmrg 1383a966c04fSmrg } 1384a966c04fSmrg data += bpl; 1385a966c04fSmrg } 1386a966c04fSmrg else 1387a966c04fSmrg for (y = 0; y < height; y++) { 1388a966c04fSmrg data_ptr = data; 1389a966c04fSmrg max_data = data_ptr + (width << 2); 1390a966c04fSmrg 1391a966c04fSmrg while (data_ptr < max_data) { 1392a966c04fSmrg pixel = pixels[*(iptr++)]; 1393a966c04fSmrg 1394a966c04fSmrg *data_ptr++ = pixel; 1395a966c04fSmrg *data_ptr++ = pixel >> 8; 1396a966c04fSmrg *data_ptr++ = pixel >> 16; 1397a966c04fSmrg *data_ptr++ = pixel >> 24; 1398a966c04fSmrg } 1399a966c04fSmrg data += bpl; 1400a966c04fSmrg } 1401a966c04fSmrg 1402a966c04fSmrg#endif /* WITHOUT_SPEEDUPS */ 1403a966c04fSmrg} 1404a966c04fSmrg 1405a966c04fSmrg/* 1406a966c04fSmrg * write pixels into a 16-bits Z image data structure 1407a966c04fSmrg */ 1408a966c04fSmrg 1409a966c04fSmrgstatic void 14102e2dd055SmrgPutImagePixels16( 14112e2dd055Smrg XImage *image, 14122e2dd055Smrg unsigned int width, 14132e2dd055Smrg unsigned int height, 14142e2dd055Smrg unsigned int *pixelindex, 14152e2dd055Smrg Pixel *pixels) 1416a966c04fSmrg{ 1417a966c04fSmrg unsigned char *data; 1418a966c04fSmrg unsigned int *iptr; 1419a966c04fSmrg unsigned int y; 1420a966c04fSmrg 1421a966c04fSmrg#ifdef WITHOUT_SPEEDUPS 1422a966c04fSmrg 1423a966c04fSmrg unsigned int x; 1424a966c04fSmrg unsigned char *addr; 1425a966c04fSmrg 1426a966c04fSmrg data = (unsigned char *) image->data; 1427a966c04fSmrg iptr = pixelindex; 1428a966c04fSmrg if (image->byte_order == MSBFirst) 1429a966c04fSmrg for (y = 0; y < height; y++) 1430a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 1431a966c04fSmrg addr = &data[ZINDEX16(x, y, image)]; 1432a966c04fSmrg addr[0] = pixels[*iptr] >> 8; 1433a966c04fSmrg addr[1] = pixels[*iptr]; 1434a966c04fSmrg } 1435a966c04fSmrg else 1436a966c04fSmrg for (y = 0; y < height; y++) 1437a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 1438a966c04fSmrg addr = &data[ZINDEX16(x, y, image)]; 1439a966c04fSmrg addr[0] = pixels[*iptr]; 1440a966c04fSmrg addr[1] = pixels[*iptr] >> 8; 1441a966c04fSmrg } 1442a966c04fSmrg 1443a966c04fSmrg#else /* WITHOUT_SPEEDUPS */ 1444a966c04fSmrg 1445a966c04fSmrg Pixel pixel; 1446a966c04fSmrg 1447a966c04fSmrg unsigned int bpl = image->bytes_per_line; 1448a966c04fSmrg unsigned char *data_ptr, *max_data; 1449a966c04fSmrg 1450a966c04fSmrg data = (unsigned char *) image->data; 1451a966c04fSmrg iptr = pixelindex; 1452a966c04fSmrg if (image->byte_order == MSBFirst) 1453a966c04fSmrg for (y = 0; y < height; y++) { 1454a966c04fSmrg data_ptr = data; 1455a966c04fSmrg max_data = data_ptr + (width << 1); 1456a966c04fSmrg 1457a966c04fSmrg while (data_ptr < max_data) { 1458a966c04fSmrg pixel = pixels[*(iptr++)]; 1459a966c04fSmrg 1460a966c04fSmrg data_ptr[0] = pixel >> 8; 1461a966c04fSmrg data_ptr[1] = pixel; 1462a966c04fSmrg 1463a966c04fSmrg data_ptr += (1 << 1); 1464a966c04fSmrg } 1465a966c04fSmrg data += bpl; 1466a966c04fSmrg } 1467a966c04fSmrg else 1468a966c04fSmrg for (y = 0; y < height; y++) { 1469a966c04fSmrg data_ptr = data; 1470a966c04fSmrg max_data = data_ptr + (width << 1); 1471a966c04fSmrg 1472a966c04fSmrg while (data_ptr < max_data) { 1473a966c04fSmrg pixel = pixels[*(iptr++)]; 1474a966c04fSmrg 1475a966c04fSmrg data_ptr[0] = pixel; 1476a966c04fSmrg data_ptr[1] = pixel >> 8; 1477a966c04fSmrg 1478a966c04fSmrg data_ptr += (1 << 1); 1479a966c04fSmrg } 1480a966c04fSmrg data += bpl; 1481a966c04fSmrg } 1482a966c04fSmrg 1483a966c04fSmrg#endif /* WITHOUT_SPEEDUPS */ 1484a966c04fSmrg} 1485a966c04fSmrg 1486a966c04fSmrg/* 1487a966c04fSmrg * write pixels into a 8-bits Z image data structure 1488a966c04fSmrg */ 1489a966c04fSmrg 1490a966c04fSmrgstatic void 14912e2dd055SmrgPutImagePixels8( 14922e2dd055Smrg XImage *image, 14932e2dd055Smrg unsigned int width, 14942e2dd055Smrg unsigned int height, 14952e2dd055Smrg unsigned int *pixelindex, 14962e2dd055Smrg Pixel *pixels) 1497a966c04fSmrg{ 1498a966c04fSmrg char *data; 1499a966c04fSmrg unsigned int *iptr; 1500a966c04fSmrg unsigned int y; 1501a966c04fSmrg 1502a966c04fSmrg#ifdef WITHOUT_SPEEDUPS 1503a966c04fSmrg 1504a966c04fSmrg unsigned int x; 1505a966c04fSmrg 1506a966c04fSmrg data = image->data; 1507a966c04fSmrg iptr = pixelindex; 1508a966c04fSmrg for (y = 0; y < height; y++) 1509a966c04fSmrg for (x = 0; x < width; x++, iptr++) 1510a966c04fSmrg data[ZINDEX8(x, y, image)] = pixels[*iptr]; 1511a966c04fSmrg 1512a966c04fSmrg#else /* WITHOUT_SPEEDUPS */ 1513a966c04fSmrg 1514a966c04fSmrg unsigned int bpl = image->bytes_per_line; 1515a966c04fSmrg char *data_ptr, *max_data; 1516a966c04fSmrg 1517a966c04fSmrg data = image->data; 1518a966c04fSmrg iptr = pixelindex; 1519a966c04fSmrg 1520a966c04fSmrg for (y = 0; y < height; y++) { 1521a966c04fSmrg data_ptr = data; 1522a966c04fSmrg max_data = data_ptr + width; 1523a966c04fSmrg 1524a966c04fSmrg while (data_ptr < max_data) 1525a966c04fSmrg *(data_ptr++) = pixels[*(iptr++)]; 1526a966c04fSmrg 1527a966c04fSmrg data += bpl; 1528a966c04fSmrg } 1529a966c04fSmrg 1530a966c04fSmrg#endif /* WITHOUT_SPEEDUPS */ 1531a966c04fSmrg} 1532a966c04fSmrg 1533a966c04fSmrg/* 1534a966c04fSmrg * write pixels into a 1-bit depth image data structure and **offset null** 1535a966c04fSmrg */ 1536a966c04fSmrg 1537a966c04fSmrgstatic void 15382e2dd055SmrgPutImagePixels1( 15392e2dd055Smrg XImage *image, 15402e2dd055Smrg unsigned int width, 15412e2dd055Smrg unsigned int height, 15422e2dd055Smrg unsigned int *pixelindex, 15432e2dd055Smrg Pixel *pixels) 1544a966c04fSmrg{ 1545a966c04fSmrg if (image->byte_order != image->bitmap_bit_order) 1546a966c04fSmrg PutImagePixels(image, width, height, pixelindex, pixels); 1547a966c04fSmrg else { 1548a966c04fSmrg unsigned int *iptr; 1549a966c04fSmrg unsigned int y; 1550a966c04fSmrg char *data; 1551a966c04fSmrg 1552a966c04fSmrg#ifdef WITHOUT_SPEEDUPS 1553a966c04fSmrg 1554a966c04fSmrg unsigned int x; 1555a966c04fSmrg 1556a966c04fSmrg data = image->data; 1557a966c04fSmrg iptr = pixelindex; 1558a966c04fSmrg if (image->bitmap_bit_order == MSBFirst) 1559a966c04fSmrg for (y = 0; y < height; y++) 1560a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 1561a966c04fSmrg if (pixels[*iptr] & 1) 1562a966c04fSmrg data[ZINDEX1(x, y, image)] |= 0x80 >> (x & 7); 1563a966c04fSmrg else 1564a966c04fSmrg data[ZINDEX1(x, y, image)] &= ~(0x80 >> (x & 7)); 1565a966c04fSmrg } 1566a966c04fSmrg else 1567a966c04fSmrg for (y = 0; y < height; y++) 1568a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 1569a966c04fSmrg if (pixels[*iptr] & 1) 1570a966c04fSmrg data[ZINDEX1(x, y, image)] |= 1 << (x & 7); 1571a966c04fSmrg else 1572a966c04fSmrg data[ZINDEX1(x, y, image)] &= ~(1 << (x & 7)); 1573a966c04fSmrg } 1574a966c04fSmrg 1575a966c04fSmrg#else /* WITHOUT_SPEEDUPS */ 1576a966c04fSmrg 1577a966c04fSmrg char value; 1578a966c04fSmrg char *data_ptr, *max_data; 1579a966c04fSmrg int bpl = image->bytes_per_line; 1580a966c04fSmrg int diff, count; 1581a966c04fSmrg 1582a966c04fSmrg data = image->data; 1583a966c04fSmrg iptr = pixelindex; 1584a966c04fSmrg 1585a966c04fSmrg diff = width & 7; 1586a966c04fSmrg width >>= 3; 1587a966c04fSmrg 1588a966c04fSmrg if (image->bitmap_bit_order == MSBFirst) 1589a966c04fSmrg for (y = 0; y < height; y++) { 1590a966c04fSmrg data_ptr = data; 1591a966c04fSmrg max_data = data_ptr + width; 1592a966c04fSmrg while (data_ptr < max_data) { 1593a966c04fSmrg value = 0; 1594a966c04fSmrg 1595a966c04fSmrg value = (value << 1) | (pixels[*(iptr++)] & 1); 1596a966c04fSmrg value = (value << 1) | (pixels[*(iptr++)] & 1); 1597a966c04fSmrg value = (value << 1) | (pixels[*(iptr++)] & 1); 1598a966c04fSmrg value = (value << 1) | (pixels[*(iptr++)] & 1); 1599a966c04fSmrg value = (value << 1) | (pixels[*(iptr++)] & 1); 1600a966c04fSmrg value = (value << 1) | (pixels[*(iptr++)] & 1); 1601a966c04fSmrg value = (value << 1) | (pixels[*(iptr++)] & 1); 1602a966c04fSmrg value = (value << 1) | (pixels[*(iptr++)] & 1); 1603a966c04fSmrg 1604a966c04fSmrg *(data_ptr++) = value; 1605a966c04fSmrg } 1606a966c04fSmrg if (diff) { 1607a966c04fSmrg value = 0; 1608a966c04fSmrg for (count = 0; count < diff; count++) { 1609a966c04fSmrg if (pixels[*(iptr++)] & 1) 1610a966c04fSmrg value |= (0x80 >> count); 1611a966c04fSmrg } 1612a966c04fSmrg *(data_ptr) = value; 1613a966c04fSmrg } 1614a966c04fSmrg data += bpl; 1615a966c04fSmrg } 1616a966c04fSmrg else 1617a966c04fSmrg for (y = 0; y < height; y++) { 1618a966c04fSmrg data_ptr = data; 1619a966c04fSmrg max_data = data_ptr + width; 1620a966c04fSmrg while (data_ptr < max_data) { 1621a966c04fSmrg value = 0; 1622a966c04fSmrg iptr += 8; 1623a966c04fSmrg 1624a966c04fSmrg value = (value << 1) | (pixels[*(--iptr)] & 1); 1625a966c04fSmrg value = (value << 1) | (pixels[*(--iptr)] & 1); 1626a966c04fSmrg value = (value << 1) | (pixels[*(--iptr)] & 1); 1627a966c04fSmrg value = (value << 1) | (pixels[*(--iptr)] & 1); 1628a966c04fSmrg value = (value << 1) | (pixels[*(--iptr)] & 1); 1629a966c04fSmrg value = (value << 1) | (pixels[*(--iptr)] & 1); 1630a966c04fSmrg value = (value << 1) | (pixels[*(--iptr)] & 1); 1631a966c04fSmrg value = (value << 1) | (pixels[*(--iptr)] & 1); 1632a966c04fSmrg 1633a966c04fSmrg iptr += 8; 1634a966c04fSmrg *(data_ptr++) = value; 1635a966c04fSmrg } 1636a966c04fSmrg if (diff) { 1637a966c04fSmrg value = 0; 1638a966c04fSmrg for (count = 0; count < diff; count++) { 1639a966c04fSmrg if (pixels[*(iptr++)] & 1) 1640a966c04fSmrg value |= (1 << count); 1641a966c04fSmrg } 1642a966c04fSmrg *(data_ptr) = value; 1643a966c04fSmrg } 1644a966c04fSmrg data += bpl; 1645a966c04fSmrg } 1646a966c04fSmrg 1647a966c04fSmrg#endif /* WITHOUT_SPEEDUPS */ 1648a966c04fSmrg } 1649a966c04fSmrg} 1650a966c04fSmrg 1651a966c04fSmrgint 16522e2dd055SmrgXpmCreatePixmapFromXpmImage( 16532e2dd055Smrg Display *display, 16542e2dd055Smrg Drawable d, 16552e2dd055Smrg XpmImage *image, 16562e2dd055Smrg Pixmap *pixmap_return, 16572e2dd055Smrg Pixmap *shapemask_return, 16582e2dd055Smrg XpmAttributes *attributes) 1659a966c04fSmrg{ 16604e08afa9Smrg XImage *ximage = NULL, *shapeimage = NULL; 1661a966c04fSmrg int ErrorStatus; 1662a966c04fSmrg 1663a966c04fSmrg /* initialize return values */ 1664a966c04fSmrg if (pixmap_return) 1665a966c04fSmrg *pixmap_return = 0; 1666a966c04fSmrg if (shapemask_return) 1667a966c04fSmrg *shapemask_return = 0; 1668a966c04fSmrg 1669a966c04fSmrg /* create the ximages */ 1670a966c04fSmrg ErrorStatus = XpmCreateImageFromXpmImage(display, image, 1671a966c04fSmrg (pixmap_return ? &ximage : NULL), 1672a966c04fSmrg (shapemask_return ? 1673a966c04fSmrg &shapeimage : NULL), 1674a966c04fSmrg attributes); 1675a966c04fSmrg if (ErrorStatus < 0) 16764e08afa9Smrg goto cleanup; 1677a966c04fSmrg 1678a966c04fSmrg /* create the pixmaps and destroy images */ 1679a966c04fSmrg if (pixmap_return && ximage) { 16804e08afa9Smrg ErrorStatus = 16814e08afa9Smrg xpmCreatePixmapFromImage(display, d, ximage, pixmap_return); 16824e08afa9Smrg if (ErrorStatus < 0) /* fatal error */ 16834e08afa9Smrg goto cleanup; 1684a966c04fSmrg } 1685a966c04fSmrg if (shapemask_return && shapeimage) { 16864e08afa9Smrg ErrorStatus = 16874e08afa9Smrg xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return); 16884e08afa9Smrg } 16894e08afa9Smrg 16904e08afa9Smrg cleanup: 16914e08afa9Smrg if (ximage != NULL) 16924e08afa9Smrg XDestroyImage(ximage); 16934e08afa9Smrg if (shapeimage != NULL) 1694a966c04fSmrg XDestroyImage(shapeimage); 16954e08afa9Smrg if (ErrorStatus < 0) { 16964e08afa9Smrg if (pixmap_return && *pixmap_return) { 16974e08afa9Smrg XFreePixmap(display, *pixmap_return); 16984e08afa9Smrg *pixmap_return = 0; 16994e08afa9Smrg } 17004e08afa9Smrg if (shapemask_return && *shapemask_return) { 17014e08afa9Smrg XFreePixmap(display, *shapemask_return); 17024e08afa9Smrg *shapemask_return = 0; 17034e08afa9Smrg } 1704a966c04fSmrg } 1705a966c04fSmrg return (ErrorStatus); 1706a966c04fSmrg} 1707a966c04fSmrg 1708a966c04fSmrg# else /* AMIGA */ 1709a966c04fSmrg 1710a966c04fSmrgstatic void 1711a966c04fSmrgAPutImagePixels ( 1712a966c04fSmrg XImage *image, 1713a966c04fSmrg unsigned int width, 1714a966c04fSmrg unsigned int height, 1715a966c04fSmrg unsigned int *pixelindex, 1716a966c04fSmrg Pixel *pixels) 1717a966c04fSmrg{ 1718a966c04fSmrg unsigned int *data = pixelindex; 1719a966c04fSmrg unsigned int x, y; 1720a966c04fSmrg unsigned char *array; 1721a966c04fSmrg XImage *tmp_img; 1722a966c04fSmrg BOOL success = FALSE; 172397cf2ee2Smrg 1724a966c04fSmrg array = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*array)); 1725a966c04fSmrg if (array != NULL) 1726a966c04fSmrg { 1727a966c04fSmrg tmp_img = AllocXImage ((((width+15)>>4)<<4), 1, 1728a966c04fSmrg image->rp->BitMap->Depth); 1729a966c04fSmrg if (tmp_img != NULL) 1730a966c04fSmrg { 1731a966c04fSmrg for (y = 0; y < height; ++y) 1732a966c04fSmrg { 1733a966c04fSmrg for (x = 0; x < width; ++x) 1734a966c04fSmrg array[x] = pixels[*(data++)]; 1735a966c04fSmrg WritePixelLine8 (image->rp, 0, y, width, array, tmp_img->rp); 1736a966c04fSmrg } 1737a966c04fSmrg FreeXImage (tmp_img); 1738a966c04fSmrg success = TRUE; 1739a966c04fSmrg } 1740a966c04fSmrg XpmFree (array); 1741a966c04fSmrg } 174297cf2ee2Smrg 1743a966c04fSmrg if (!success) 1744a966c04fSmrg { 1745a966c04fSmrg for (y = 0; y < height; ++y) 1746a966c04fSmrg for (x = 0; x < width; ++x) 1747a966c04fSmrg XPutPixel (image, x, y, pixels[*(data++)]); 1748a966c04fSmrg } 1749a966c04fSmrg} 1750a966c04fSmrg 1751a966c04fSmrg# endif/* AMIGA */ 1752a966c04fSmrg#else /* FOR_MSW part follows */ 1753a966c04fSmrgstatic void 17542e2dd055SmrgMSWPutImagePixels( 17552e2dd055Smrg Display *dc, 17562e2dd055Smrg XImage *image, 17572e2dd055Smrg unsigned int width, 17582e2dd055Smrg unsigned int height, 17592e2dd055Smrg unsigned int *pixelindex, 17602e2dd055Smrg Pixel *pixels) 1761a966c04fSmrg{ 1762a966c04fSmrg unsigned int *data = pixelindex; 1763a966c04fSmrg unsigned int x, y; 1764a966c04fSmrg HBITMAP obm; 1765a966c04fSmrg 1766a966c04fSmrg obm = SelectObject(*dc, image->bitmap); 1767a966c04fSmrg for (y = 0; y < height; y++) { 1768a966c04fSmrg for (x = 0; x < width; x++) { 1769a966c04fSmrg SetPixel(*dc, x, y, pixels[*(data++)]); /* data is [x+y*width] */ 1770a966c04fSmrg } 1771a966c04fSmrg } 1772a966c04fSmrg SelectObject(*dc, obm); 1773a966c04fSmrg} 1774a966c04fSmrg 1775a966c04fSmrg#endif /* FOR_MSW */ 1776a966c04fSmrg 1777a966c04fSmrg 1778a966c04fSmrg 1779a966c04fSmrg#if !defined(FOR_MSW) && !defined(AMIGA) 1780a966c04fSmrg 1781a966c04fSmrgstatic int 17822e2dd055SmrgPutPixel1( 17832e2dd055Smrg register XImage *ximage, 17842e2dd055Smrg int x, 17852e2dd055Smrg int y, 17862e2dd055Smrg unsigned long pixel) 1787a966c04fSmrg{ 1788a966c04fSmrg register char *src; 1789a966c04fSmrg register char *dst; 1790a966c04fSmrg register int i; 1791a966c04fSmrg Pixel px; 1792a966c04fSmrg int nbytes; 1793a966c04fSmrg 1794a966c04fSmrg if(x < 0 || y < 0) 1795a966c04fSmrg return 0; 1796a966c04fSmrg 1797a966c04fSmrg for (i=0, px=pixel; i<sizeof(unsigned long); i++, px>>=8) 1798a966c04fSmrg ((unsigned char *)&pixel)[i] = px; 1799a966c04fSmrg src = &ximage->data[XYINDEX(x, y, ximage)]; 1800a966c04fSmrg dst = (char *)&px; 1801a966c04fSmrg px = 0; 1802a966c04fSmrg nbytes = ximage->bitmap_unit >> 3; 1803a966c04fSmrg for (i = nbytes; --i >= 0; ) *dst++ = *src++; 1804a966c04fSmrg XYNORMALIZE(&px, ximage); 1805a966c04fSmrg i = ((x + ximage->xoffset) % ximage->bitmap_unit); 1806a966c04fSmrg _putbits ((char *)&pixel, i, 1, (char *)&px); 1807a966c04fSmrg XYNORMALIZE(&px, ximage); 1808a966c04fSmrg src = (char *) &px; 1809a966c04fSmrg dst = &ximage->data[XYINDEX(x, y, ximage)]; 1810a966c04fSmrg for (i = nbytes; --i >= 0; ) 1811a966c04fSmrg *dst++ = *src++; 1812a966c04fSmrg 1813a966c04fSmrg return 1; 1814a966c04fSmrg} 1815a966c04fSmrg 1816a966c04fSmrgstatic int 18172e2dd055SmrgPutPixel( 18182e2dd055Smrg register XImage *ximage, 18192e2dd055Smrg int x, 18202e2dd055Smrg int y, 18212e2dd055Smrg unsigned long pixel) 1822a966c04fSmrg{ 1823a966c04fSmrg register char *src; 1824a966c04fSmrg register char *dst; 1825a966c04fSmrg register int i; 1826a966c04fSmrg Pixel px; 1827a966c04fSmrg unsigned int nbytes, ibpp; 1828a966c04fSmrg 1829a966c04fSmrg if(x < 0 || y < 0) 1830a966c04fSmrg return 0; 1831a966c04fSmrg 1832a966c04fSmrg ibpp = ximage->bits_per_pixel; 1833a966c04fSmrg if (ximage->depth == 4) 1834a966c04fSmrg pixel &= 0xf; 1835a966c04fSmrg for (i = 0, px = pixel; i < sizeof(unsigned long); i++, px >>= 8) 1836a966c04fSmrg ((unsigned char *) &pixel)[i] = px; 1837a966c04fSmrg src = &ximage->data[ZINDEX(x, y, ximage)]; 1838a966c04fSmrg dst = (char *) &px; 1839a966c04fSmrg px = 0; 1840a966c04fSmrg nbytes = (ibpp + 7) >> 3; 1841a966c04fSmrg for (i = nbytes; --i >= 0;) 1842a966c04fSmrg *dst++ = *src++; 1843a966c04fSmrg ZNORMALIZE(&px, ximage); 1844a966c04fSmrg _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px); 1845a966c04fSmrg ZNORMALIZE(&px, ximage); 1846a966c04fSmrg src = (char *) &px; 1847a966c04fSmrg dst = &ximage->data[ZINDEX(x, y, ximage)]; 1848a966c04fSmrg for (i = nbytes; --i >= 0;) 1849a966c04fSmrg *dst++ = *src++; 1850a966c04fSmrg 1851a966c04fSmrg return 1; 1852a966c04fSmrg} 1853a966c04fSmrg 1854a966c04fSmrg#if !defined(WORD64) && !defined(LONG64) 1855a966c04fSmrgstatic int 18562e2dd055SmrgPutPixel32( 18572e2dd055Smrg register XImage *ximage, 18582e2dd055Smrg int x, 18592e2dd055Smrg int y, 18602e2dd055Smrg unsigned long pixel) 1861a966c04fSmrg{ 1862a966c04fSmrg unsigned char *addr; 1863a966c04fSmrg 1864a966c04fSmrg if(x < 0 || y < 0) 1865a966c04fSmrg return 0; 1866a966c04fSmrg 1867a966c04fSmrg addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; 1868a966c04fSmrg *((unsigned long *)addr) = pixel; 1869a966c04fSmrg return 1; 1870a966c04fSmrg} 1871a966c04fSmrg#endif 1872a966c04fSmrg 1873a966c04fSmrgstatic int 18742e2dd055SmrgPutPixel32MSB( 18752e2dd055Smrg register XImage *ximage, 18762e2dd055Smrg int x, 18772e2dd055Smrg int y, 18782e2dd055Smrg unsigned long pixel) 1879a966c04fSmrg{ 1880a966c04fSmrg unsigned char *addr; 1881a966c04fSmrg 1882a966c04fSmrg if(x < 0 || y < 0) 1883a966c04fSmrg return 0; 1884a966c04fSmrg 1885a966c04fSmrg addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; 1886a966c04fSmrg addr[0] = pixel >> 24; 1887a966c04fSmrg addr[1] = pixel >> 16; 1888a966c04fSmrg addr[2] = pixel >> 8; 1889a966c04fSmrg addr[3] = pixel; 1890a966c04fSmrg return 1; 1891a966c04fSmrg} 1892a966c04fSmrg 1893a966c04fSmrgstatic int 18942e2dd055SmrgPutPixel32LSB( 18952e2dd055Smrg register XImage *ximage, 18962e2dd055Smrg int x, 18972e2dd055Smrg int y, 18982e2dd055Smrg unsigned long pixel) 1899a966c04fSmrg{ 1900a966c04fSmrg unsigned char *addr; 1901a966c04fSmrg 1902a966c04fSmrg if(x < 0 || y < 0) 1903a966c04fSmrg return 0; 1904a966c04fSmrg 1905a966c04fSmrg addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; 1906a966c04fSmrg addr[3] = pixel >> 24; 1907a966c04fSmrg addr[2] = pixel >> 16; 1908a966c04fSmrg addr[1] = pixel >> 8; 1909a966c04fSmrg addr[0] = pixel; 1910a966c04fSmrg return 1; 1911a966c04fSmrg} 1912a966c04fSmrg 1913a966c04fSmrgstatic int 19142e2dd055SmrgPutPixel16MSB( 19152e2dd055Smrg register XImage *ximage, 19162e2dd055Smrg int x, 19172e2dd055Smrg int y, 19182e2dd055Smrg unsigned long pixel) 1919a966c04fSmrg{ 1920a966c04fSmrg unsigned char *addr; 192197cf2ee2Smrg 1922a966c04fSmrg if(x < 0 || y < 0) 1923a966c04fSmrg return 0; 1924a966c04fSmrg 1925a966c04fSmrg addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)]; 1926a966c04fSmrg addr[0] = pixel >> 8; 1927a966c04fSmrg addr[1] = pixel; 1928a966c04fSmrg return 1; 1929a966c04fSmrg} 1930a966c04fSmrg 1931a966c04fSmrgstatic int 19322e2dd055SmrgPutPixel16LSB( 19332e2dd055Smrg register XImage *ximage, 19342e2dd055Smrg int x, 19352e2dd055Smrg int y, 19362e2dd055Smrg unsigned long pixel) 1937a966c04fSmrg{ 1938a966c04fSmrg unsigned char *addr; 193997cf2ee2Smrg 1940a966c04fSmrg if(x < 0 || y < 0) 1941a966c04fSmrg return 0; 1942a966c04fSmrg 1943a966c04fSmrg addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)]; 1944a966c04fSmrg addr[1] = pixel >> 8; 1945a966c04fSmrg addr[0] = pixel; 1946a966c04fSmrg return 1; 1947a966c04fSmrg} 1948a966c04fSmrg 1949a966c04fSmrgstatic int 19502e2dd055SmrgPutPixel8( 19512e2dd055Smrg register XImage *ximage, 19522e2dd055Smrg int x, 19532e2dd055Smrg int y, 19542e2dd055Smrg unsigned long pixel) 1955a966c04fSmrg{ 1956a966c04fSmrg if(x < 0 || y < 0) 1957a966c04fSmrg return 0; 1958a966c04fSmrg 1959a966c04fSmrg ximage->data[ZINDEX8(x, y, ximage)] = pixel; 1960a966c04fSmrg return 1; 1961a966c04fSmrg} 1962a966c04fSmrg 1963a966c04fSmrgstatic int 19642e2dd055SmrgPutPixel1MSB( 19652e2dd055Smrg register XImage *ximage, 19662e2dd055Smrg int x, 19672e2dd055Smrg int y, 19682e2dd055Smrg unsigned long pixel) 1969a966c04fSmrg{ 1970a966c04fSmrg if(x < 0 || y < 0) 1971a966c04fSmrg return 0; 1972a966c04fSmrg 1973a966c04fSmrg if (pixel & 1) 1974a966c04fSmrg ximage->data[ZINDEX1(x, y, ximage)] |= 0x80 >> (x & 7); 1975a966c04fSmrg else 1976a966c04fSmrg ximage->data[ZINDEX1(x, y, ximage)] &= ~(0x80 >> (x & 7)); 1977a966c04fSmrg return 1; 1978a966c04fSmrg} 1979a966c04fSmrg 1980a966c04fSmrgstatic int 19812e2dd055SmrgPutPixel1LSB( 19822e2dd055Smrg register XImage *ximage, 19832e2dd055Smrg int x, 19842e2dd055Smrg int y, 19852e2dd055Smrg unsigned long pixel) 1986a966c04fSmrg{ 1987a966c04fSmrg if(x < 0 || y < 0) 1988a966c04fSmrg return 0; 1989a966c04fSmrg 1990a966c04fSmrg if (pixel & 1) 1991a966c04fSmrg ximage->data[ZINDEX1(x, y, ximage)] |= 1 << (x & 7); 1992a966c04fSmrg else 1993a966c04fSmrg ximage->data[ZINDEX1(x, y, ximage)] &= ~(1 << (x & 7)); 1994a966c04fSmrg return 1; 1995a966c04fSmrg} 1996a966c04fSmrg 1997a966c04fSmrg#endif /* not FOR_MSW && not AMIGA */ 1998a966c04fSmrg 1999a966c04fSmrg/* 2000a966c04fSmrg * This function parses an Xpm file or data and directly create an XImage 2001a966c04fSmrg */ 2002a966c04fSmrgint 20032e2dd055SmrgxpmParseDataAndCreate( 20042e2dd055Smrg Display *display, 20052e2dd055Smrg xpmData *data, 20062e2dd055Smrg XImage **image_return, 20072e2dd055Smrg XImage **shapeimage_return, 20082e2dd055Smrg XpmImage *image, 20092e2dd055Smrg XpmInfo *info, 20102e2dd055Smrg XpmAttributes *attributes) 2011a966c04fSmrg{ 2012a966c04fSmrg /* variables stored in the XpmAttributes structure */ 2013a966c04fSmrg Visual *visual; 2014a966c04fSmrg Colormap colormap; 2015a966c04fSmrg unsigned int depth; 2016a966c04fSmrg int bitmap_format; 2017a966c04fSmrg XpmFreeColorsFunc freeColors; 2018a966c04fSmrg 2019a966c04fSmrg /* variables to return */ 2020a966c04fSmrg XImage *ximage = NULL; 2021a966c04fSmrg XImage *shapeimage = NULL; 2022a966c04fSmrg unsigned int mask_pixel_index = XpmUndefPixel; 2023a966c04fSmrg 2024a966c04fSmrg /* calculation variables */ 2025a966c04fSmrg Pixel *image_pixels = NULL; 2026a966c04fSmrg Pixel *mask_pixels = NULL; 2027a966c04fSmrg Pixel *alloc_pixels = NULL; 2028a966c04fSmrg Pixel *used_pixels = NULL; 2029a966c04fSmrg unsigned int nalloc_pixels = 0; 2030a966c04fSmrg unsigned int nused_pixels = 0; 2031a966c04fSmrg unsigned int width, height, ncolors, cpp; 2032a966c04fSmrg unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0; 2033a966c04fSmrg XpmColor *colorTable = NULL; 2034a966c04fSmrg char *hints_cmt = NULL; 2035a966c04fSmrg char *colors_cmt = NULL; 2036a966c04fSmrg char *pixels_cmt = NULL; 2037a966c04fSmrg 2038a966c04fSmrg unsigned int cmts; 2039a966c04fSmrg int ErrorStatus; 2040a966c04fSmrg xpmHashTable hashtable; 2041a966c04fSmrg 2042a966c04fSmrg 2043a966c04fSmrg /* initialize return values */ 2044a966c04fSmrg if (image_return) 2045a966c04fSmrg *image_return = NULL; 2046a966c04fSmrg if (shapeimage_return) 2047a966c04fSmrg *shapeimage_return = NULL; 2048a966c04fSmrg 2049a966c04fSmrg 2050a966c04fSmrg /* retrieve information from the XpmAttributes */ 2051a966c04fSmrg if (attributes && (attributes->valuemask & XpmVisual)) 2052a966c04fSmrg visual = attributes->visual; 2053a966c04fSmrg else 2054a966c04fSmrg visual = XDefaultVisual(display, XDefaultScreen(display)); 2055a966c04fSmrg 2056a966c04fSmrg if (attributes && (attributes->valuemask & XpmColormap)) 2057a966c04fSmrg colormap = attributes->colormap; 2058a966c04fSmrg else 2059a966c04fSmrg colormap = XDefaultColormap(display, XDefaultScreen(display)); 2060a966c04fSmrg 2061a966c04fSmrg if (attributes && (attributes->valuemask & XpmDepth)) 2062a966c04fSmrg depth = attributes->depth; 2063a966c04fSmrg else 2064a966c04fSmrg depth = XDefaultDepth(display, XDefaultScreen(display)); 2065a966c04fSmrg 2066a966c04fSmrg if (attributes && (attributes->valuemask & XpmBitmapFormat)) 2067a966c04fSmrg bitmap_format = attributes->bitmap_format; 2068a966c04fSmrg else 2069a966c04fSmrg bitmap_format = ZPixmap; 2070a966c04fSmrg 2071a966c04fSmrg if (attributes && (attributes->valuemask & XpmFreeColors)) 2072a966c04fSmrg freeColors = attributes->free_colors; 2073a966c04fSmrg else 2074a966c04fSmrg freeColors = FreeColors; 2075a966c04fSmrg 2076a966c04fSmrg cmts = info && (info->valuemask & XpmReturnComments); 2077a966c04fSmrg 2078a966c04fSmrg /* 2079a966c04fSmrg * parse the header 2080a966c04fSmrg */ 2081a966c04fSmrg ErrorStatus = xpmParseHeader(data); 2082a966c04fSmrg if (ErrorStatus != XpmSuccess) 2083a966c04fSmrg return (ErrorStatus); 2084a966c04fSmrg 2085a966c04fSmrg /* 2086a966c04fSmrg * read values 2087a966c04fSmrg */ 2088a966c04fSmrg ErrorStatus = xpmParseValues(data, &width, &height, &ncolors, &cpp, 2089a966c04fSmrg &x_hotspot, &y_hotspot, &hotspot, 2090a966c04fSmrg &extensions); 2091a966c04fSmrg if (ErrorStatus != XpmSuccess) 2092a966c04fSmrg return (ErrorStatus); 2093a966c04fSmrg 2094a966c04fSmrg /* 2095a966c04fSmrg * store the hints comment line 2096a966c04fSmrg */ 2097a966c04fSmrg if (cmts) 2098a966c04fSmrg xpmGetCmt(data, &hints_cmt); 2099a966c04fSmrg 2100a966c04fSmrg /* 2101a966c04fSmrg * init the hashtable 2102a966c04fSmrg */ 2103a966c04fSmrg if (USE_HASHTABLE) { 2104a966c04fSmrg ErrorStatus = xpmHashTableInit(&hashtable); 2105a966c04fSmrg if (ErrorStatus != XpmSuccess) 2106a966c04fSmrg RETURN(ErrorStatus); 2107a966c04fSmrg } 2108a966c04fSmrg 2109a966c04fSmrg /* 2110a966c04fSmrg * read colors 2111a966c04fSmrg */ 2112a966c04fSmrg ErrorStatus = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable); 2113a966c04fSmrg if (ErrorStatus != XpmSuccess) 2114a966c04fSmrg RETURN(ErrorStatus); 2115a966c04fSmrg 2116a966c04fSmrg /* 2117a966c04fSmrg * store the colors comment line 2118a966c04fSmrg */ 2119a966c04fSmrg if (cmts) 2120a966c04fSmrg xpmGetCmt(data, &colors_cmt); 2121a966c04fSmrg 2122a966c04fSmrg /* malloc pixels index tables */ 212397cf2ee2Smrg if (ncolors >= UINT_MAX / sizeof(Pixel)) 2124a966c04fSmrg RETURN(XpmNoMemory); 2125a966c04fSmrg 2126a966c04fSmrg image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); 2127a966c04fSmrg if (!image_pixels) 2128a966c04fSmrg RETURN(XpmNoMemory); 2129a966c04fSmrg 2130a966c04fSmrg mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); 2131a966c04fSmrg if (!mask_pixels) 2132a966c04fSmrg RETURN(XpmNoMemory); 2133a966c04fSmrg 2134a966c04fSmrg /* maximum of allocated pixels will be the number of colors */ 2135a966c04fSmrg alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); 2136a966c04fSmrg if (!alloc_pixels) 2137a966c04fSmrg RETURN(XpmNoMemory); 2138a966c04fSmrg 2139a966c04fSmrg /* maximum of allocated pixels will be the number of colors */ 2140a966c04fSmrg used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); 2141a966c04fSmrg if (!used_pixels) 2142a966c04fSmrg RETURN(XpmNoMemory); 2143a966c04fSmrg 2144a966c04fSmrg /* get pixel colors, store them in index tables */ 2145a966c04fSmrg ErrorStatus = CreateColors(display, attributes, colorTable, ncolors, 2146a966c04fSmrg image_pixels, mask_pixels, &mask_pixel_index, 2147a966c04fSmrg alloc_pixels, &nalloc_pixels, used_pixels, 2148a966c04fSmrg &nused_pixels); 2149a966c04fSmrg 2150a966c04fSmrg if (ErrorStatus != XpmSuccess 2151a966c04fSmrg && (ErrorStatus < 0 || (attributes 2152a966c04fSmrg && (attributes->valuemask & XpmExactColors) 2153a966c04fSmrg && attributes->exactColors))) 2154a966c04fSmrg RETURN(ErrorStatus); 2155a966c04fSmrg 2156a966c04fSmrg /* now create the ximage */ 2157a966c04fSmrg if (image_return) { 2158a966c04fSmrg ErrorStatus = CreateXImage(display, visual, depth, 2159a966c04fSmrg (depth == 1 ? bitmap_format : ZPixmap), 2160a966c04fSmrg width, height, &ximage); 2161a966c04fSmrg if (ErrorStatus != XpmSuccess) 2162a966c04fSmrg RETURN(ErrorStatus); 2163a966c04fSmrg 2164a966c04fSmrg#if !defined(FOR_MSW) && !defined(AMIGA) 2165a966c04fSmrg 2166a966c04fSmrg /* 2167a966c04fSmrg * set the XImage pointer function, to be used with XPutPixel, 2168a966c04fSmrg * to an internal optimized function 2169a966c04fSmrg */ 2170a966c04fSmrg 2171a966c04fSmrg if (ximage->bits_per_pixel == 8) 2172a966c04fSmrg ximage->f.put_pixel = PutPixel8; 2173a966c04fSmrg else if (((ximage->bits_per_pixel | ximage->depth) == 1) && 2174a966c04fSmrg (ximage->byte_order == ximage->bitmap_bit_order)) 2175a966c04fSmrg if (ximage->bitmap_bit_order == MSBFirst) 2176a966c04fSmrg ximage->f.put_pixel = PutPixel1MSB; 2177a966c04fSmrg else 2178a966c04fSmrg ximage->f.put_pixel = PutPixel1LSB; 2179a966c04fSmrg else if (ximage->bits_per_pixel == 16) 2180a966c04fSmrg if (ximage->bitmap_bit_order == MSBFirst) 2181a966c04fSmrg ximage->f.put_pixel = PutPixel16MSB; 2182a966c04fSmrg else 2183a966c04fSmrg ximage->f.put_pixel = PutPixel16LSB; 2184a966c04fSmrg else if (ximage->bits_per_pixel == 32) 2185a966c04fSmrg#if !defined(WORD64) && !defined(LONG64) 2186a966c04fSmrg if (*((char *)&byteorderpixel) == ximage->byte_order) 2187a966c04fSmrg ximage->f.put_pixel = PutPixel32; 2188a966c04fSmrg else 2189a966c04fSmrg#endif 2190a966c04fSmrg if (ximage->bitmap_bit_order == MSBFirst) 2191a966c04fSmrg ximage->f.put_pixel = PutPixel32MSB; 2192a966c04fSmrg else 2193a966c04fSmrg ximage->f.put_pixel = PutPixel32LSB; 2194a966c04fSmrg else if ((ximage->bits_per_pixel | ximage->depth) == 1) 2195a966c04fSmrg ximage->f.put_pixel = PutPixel1; 2196a966c04fSmrg else 2197a966c04fSmrg ximage->f.put_pixel = PutPixel; 2198a966c04fSmrg#endif /* not FOR_MSW && not AMIGA */ 2199a966c04fSmrg } 2200a966c04fSmrg 2201a966c04fSmrg /* create the shape mask image */ 2202a966c04fSmrg if (mask_pixel_index != XpmUndefPixel && shapeimage_return) { 2203a966c04fSmrg ErrorStatus = CreateXImage(display, visual, 1, bitmap_format, 2204a966c04fSmrg width, height, &shapeimage); 2205a966c04fSmrg if (ErrorStatus != XpmSuccess) 2206a966c04fSmrg RETURN(ErrorStatus); 2207a966c04fSmrg 2208a966c04fSmrg#if !defined(FOR_MSW) && !defined(AMIGA) 2209a966c04fSmrg if (shapeimage->bitmap_bit_order == MSBFirst) 2210a966c04fSmrg shapeimage->f.put_pixel = PutPixel1MSB; 2211a966c04fSmrg else 2212a966c04fSmrg shapeimage->f.put_pixel = PutPixel1LSB; 2213a966c04fSmrg#endif 2214a966c04fSmrg } 2215a966c04fSmrg 2216a966c04fSmrg /* 2217a966c04fSmrg * read pixels and put them in the XImage 2218a966c04fSmrg */ 2219a966c04fSmrg ErrorStatus = ParseAndPutPixels( 2220a966c04fSmrg#ifdef FOR_MSW 2221a966c04fSmrg display, 2222a966c04fSmrg#endif 2223a966c04fSmrg data, width, height, ncolors, cpp, 2224a966c04fSmrg colorTable, &hashtable, 2225a966c04fSmrg ximage, image_pixels, 2226a966c04fSmrg shapeimage, mask_pixels); 2227a966c04fSmrg XpmFree(image_pixels); 2228a966c04fSmrg image_pixels = NULL; 2229a966c04fSmrg XpmFree(mask_pixels); 2230a966c04fSmrg mask_pixels = NULL; 2231a966c04fSmrg 2232a966c04fSmrg /* 2233a966c04fSmrg * free the hastable 2234a966c04fSmrg */ 2235a966c04fSmrg if (ErrorStatus != XpmSuccess) 2236a966c04fSmrg RETURN(ErrorStatus); 2237a966c04fSmrg else if (USE_HASHTABLE) 2238a966c04fSmrg xpmHashTableFree(&hashtable); 2239a966c04fSmrg 2240a966c04fSmrg /* 2241a966c04fSmrg * store the pixels comment line 2242a966c04fSmrg */ 2243a966c04fSmrg if (cmts) 2244a966c04fSmrg xpmGetCmt(data, &pixels_cmt); 2245a966c04fSmrg 2246a966c04fSmrg /* 2247a966c04fSmrg * parse extensions 2248a966c04fSmrg */ 2249a966c04fSmrg if (info && (info->valuemask & XpmReturnExtensions)) { 2250a966c04fSmrg if (extensions) { 2251a966c04fSmrg ErrorStatus = xpmParseExtensions(data, &info->extensions, 2252a966c04fSmrg &info->nextensions); 2253a966c04fSmrg if (ErrorStatus != XpmSuccess) 2254a966c04fSmrg RETURN(ErrorStatus); 2255a966c04fSmrg } else { 2256a966c04fSmrg info->extensions = NULL; 2257a966c04fSmrg info->nextensions = 0; 2258a966c04fSmrg } 2259a966c04fSmrg } 2260a966c04fSmrg /* 22618b1f82e3Smrg * store found information in the XpmImage structure 2262a966c04fSmrg */ 2263a966c04fSmrg image->width = width; 2264a966c04fSmrg image->height = height; 2265a966c04fSmrg image->cpp = cpp; 2266a966c04fSmrg image->ncolors = ncolors; 2267a966c04fSmrg image->colorTable = colorTable; 2268a966c04fSmrg image->data = NULL; 2269a966c04fSmrg 2270a966c04fSmrg if (info) { 2271a966c04fSmrg if (cmts) { 2272a966c04fSmrg info->hints_cmt = hints_cmt; 2273a966c04fSmrg info->colors_cmt = colors_cmt; 2274a966c04fSmrg info->pixels_cmt = pixels_cmt; 2275a966c04fSmrg } 2276a966c04fSmrg if (hotspot) { 2277a966c04fSmrg info->x_hotspot = x_hotspot; 2278a966c04fSmrg info->y_hotspot = y_hotspot; 2279a966c04fSmrg info->valuemask |= XpmHotspot; 2280a966c04fSmrg } 2281a966c04fSmrg } 2282a966c04fSmrg /* if requested return used pixels in the XpmAttributes structure */ 2283a966c04fSmrg if (attributes && (attributes->valuemask & XpmReturnPixels || 2284a966c04fSmrg/* 3.2 backward compatibility code */ 2285a966c04fSmrg attributes->valuemask & XpmReturnInfos)) { 2286a966c04fSmrg/* end 3.2 bc */ 2287a966c04fSmrg attributes->pixels = used_pixels; 2288a966c04fSmrg attributes->npixels = nused_pixels; 2289a966c04fSmrg attributes->mask_pixel = mask_pixel_index; 2290a966c04fSmrg } else 2291a966c04fSmrg XpmFree(used_pixels); 2292a966c04fSmrg 2293a966c04fSmrg /* if requested return alloc'ed pixels in the XpmAttributes structure */ 2294a966c04fSmrg if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) { 2295a966c04fSmrg attributes->alloc_pixels = alloc_pixels; 2296a966c04fSmrg attributes->nalloc_pixels = nalloc_pixels; 2297a966c04fSmrg } else 2298a966c04fSmrg XpmFree(alloc_pixels); 2299a966c04fSmrg 2300a966c04fSmrg /* return created images */ 2301a966c04fSmrg if (image_return) 2302a966c04fSmrg *image_return = ximage; 2303a966c04fSmrg if (shapeimage_return) 2304a966c04fSmrg *shapeimage_return = shapeimage; 2305a966c04fSmrg 2306a966c04fSmrg return (XpmSuccess); 2307a966c04fSmrg 2308a966c04fSmrg/* exit point in case of error, free only locally allocated variables */ 2309a966c04fSmrgerror: 2310a966c04fSmrg if (USE_HASHTABLE) 2311a966c04fSmrg xpmHashTableFree(&hashtable); 2312a966c04fSmrg if (colorTable) 2313a966c04fSmrg xpmFreeColorTable(colorTable, ncolors); 2314a966c04fSmrg if (hints_cmt) 2315a966c04fSmrg XpmFree(hints_cmt); 2316a966c04fSmrg if (colors_cmt) 2317a966c04fSmrg XpmFree(colors_cmt); 2318a966c04fSmrg if (pixels_cmt) 2319a966c04fSmrg XpmFree(pixels_cmt); 2320a966c04fSmrg if (ximage) 2321a966c04fSmrg XDestroyImage(ximage); 2322a966c04fSmrg if (shapeimage) 2323a966c04fSmrg XDestroyImage(shapeimage); 2324a966c04fSmrg if (image_pixels) 2325a966c04fSmrg XpmFree(image_pixels); 2326a966c04fSmrg if (mask_pixels) 2327a966c04fSmrg XpmFree(mask_pixels); 2328a966c04fSmrg if (nalloc_pixels) 2329a966c04fSmrg (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL); 2330a966c04fSmrg if (alloc_pixels) 2331a966c04fSmrg XpmFree(alloc_pixels); 2332a966c04fSmrg if (used_pixels) 2333a966c04fSmrg XpmFree(used_pixels); 2334a966c04fSmrg 2335a966c04fSmrg return (ErrorStatus); 2336a966c04fSmrg} 2337a966c04fSmrg 2338a966c04fSmrgstatic int 2339a966c04fSmrgParseAndPutPixels( 2340a966c04fSmrg#ifdef FOR_MSW 23412e2dd055Smrg Display *dc, 2342a966c04fSmrg#endif 23432e2dd055Smrg xpmData *data, 23442e2dd055Smrg unsigned int width, 23452e2dd055Smrg unsigned int height, 23462e2dd055Smrg unsigned int ncolors, 23472e2dd055Smrg unsigned int cpp, 23482e2dd055Smrg XpmColor *colorTable, 23492e2dd055Smrg xpmHashTable *hashtable, 23502e2dd055Smrg XImage *image, 23512e2dd055Smrg Pixel *image_pixels, 23522e2dd055Smrg XImage *shapeimage, 23532e2dd055Smrg Pixel *shape_pixels) 2354a966c04fSmrg{ 2355a966c04fSmrg unsigned int a, x, y; 2356a966c04fSmrg 2357a966c04fSmrg switch (cpp) { 2358a966c04fSmrg 2359a966c04fSmrg case (1): /* Optimize for single character 2360a966c04fSmrg * colors */ 2361a966c04fSmrg { 2362a966c04fSmrg unsigned short colidx[256]; 2363a966c04fSmrg#ifdef FOR_MSW 2364a966c04fSmrg HDC shapedc; 2365a966c04fSmrg HBITMAP obm, sobm; 2366a966c04fSmrg 2367a966c04fSmrg if ( shapeimage ) { 2368a966c04fSmrg shapedc = CreateCompatibleDC(*dc); 2369a966c04fSmrg sobm = SelectObject(shapedc, shapeimage->bitmap); 2370a966c04fSmrg } else { 2371a966c04fSmrg shapedc = NULL; 2372a966c04fSmrg } 2373a966c04fSmrg obm = SelectObject(*dc, image->bitmap); 2374a966c04fSmrg#endif 2375a966c04fSmrg if (ncolors > 256) 2376a966c04fSmrg return (XpmFileInvalid); 2377a966c04fSmrg 2378a966c04fSmrg bzero((char *)colidx, 256 * sizeof(short)); 2379a966c04fSmrg for (a = 0; a < ncolors; a++) 2380a966c04fSmrg colidx[(unsigned char)colorTable[a].string[0]] = a + 1; 2381a966c04fSmrg 2382a966c04fSmrg for (y = 0; y < height; y++) { 2383a966c04fSmrg xpmNextString(data); 2384a966c04fSmrg for (x = 0; x < width; x++) { 2385a966c04fSmrg int c = xpmGetC(data); 2386a966c04fSmrg 2387a966c04fSmrg if (c > 0 && c < 256 && colidx[c] != 0) { 2388a966c04fSmrg#ifndef FOR_MSW 2389a966c04fSmrg XPutPixel(image, x, y, image_pixels[colidx[c] - 1]); 2390a966c04fSmrg if (shapeimage) 2391a966c04fSmrg XPutPixel(shapeimage, x, y, 2392a966c04fSmrg shape_pixels[colidx[c] - 1]); 2393a966c04fSmrg#else 2394a966c04fSmrg SetPixel(*dc, x, y, image_pixels[colidx[c] - 1]); 2395a966c04fSmrg if (shapedc) { 2396a966c04fSmrg SetPixel(shapedc, x, y, shape_pixels[colidx[c] - 1]); 2397a966c04fSmrg } 2398a966c04fSmrg#endif 2399a966c04fSmrg } else 2400a966c04fSmrg return (XpmFileInvalid); 2401a966c04fSmrg } 2402a966c04fSmrg } 2403a966c04fSmrg#ifdef FOR_MSW 2404a966c04fSmrg if ( shapedc ) { 2405a966c04fSmrg SelectObject(shapedc, sobm); 2406a966c04fSmrg DeleteDC(shapedc); 2407a966c04fSmrg } 2408a966c04fSmrg SelectObject(*dc, obm); 2409a966c04fSmrg#endif 2410a966c04fSmrg } 2411a966c04fSmrg break; 2412a966c04fSmrg 2413a966c04fSmrg case (2): /* Optimize for double character 2414a966c04fSmrg * colors */ 2415a966c04fSmrg { 2416a966c04fSmrg 2417a966c04fSmrg/* free all allocated pointers at all exits */ 2418a773ec55Smrg#define FREE_CIDX do {int f; for (f = 0; f < 256; f++) \ 2419a773ec55Smrgif (cidx[f]) XpmFree(cidx[f]);} while(0) 2420a966c04fSmrg 2421a966c04fSmrg /* array of pointers malloced by need */ 2422a966c04fSmrg unsigned short *cidx[256]; 2423a966c04fSmrg unsigned int char1; 2424a966c04fSmrg 2425a966c04fSmrg bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */ 2426a966c04fSmrg for (a = 0; a < ncolors; a++) { 2427a966c04fSmrg char1 = (unsigned char) colorTable[a].string[0]; 2428a966c04fSmrg if (cidx[char1] == NULL) { /* get new memory */ 2429a966c04fSmrg cidx[char1] = (unsigned short *) 2430a966c04fSmrg XpmCalloc(256, sizeof(unsigned short)); 2431a966c04fSmrg if (cidx[char1] == NULL) { /* new block failed */ 2432a966c04fSmrg FREE_CIDX; 2433a966c04fSmrg return (XpmNoMemory); 2434a966c04fSmrg } 2435a966c04fSmrg } 2436a966c04fSmrg cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1; 2437a966c04fSmrg } 2438a966c04fSmrg 2439a966c04fSmrg for (y = 0; y < height; y++) { 2440a966c04fSmrg xpmNextString(data); 2441a966c04fSmrg for (x = 0; x < width; x++) { 2442a966c04fSmrg int cc1 = xpmGetC(data); 2443a966c04fSmrg if (cc1 > 0 && cc1 < 256) { 2444a966c04fSmrg int cc2 = xpmGetC(data); 2445a966c04fSmrg if (cc2 > 0 && cc2 < 256 && 2446a966c04fSmrg cidx[cc1] && cidx[cc1][cc2] != 0) { 2447a966c04fSmrg#ifndef FOR_MSW 2448a966c04fSmrg XPutPixel(image, x, y, 2449a966c04fSmrg image_pixels[cidx[cc1][cc2] - 1]); 2450a966c04fSmrg if (shapeimage) 2451a966c04fSmrg XPutPixel(shapeimage, x, y, 2452a966c04fSmrg shape_pixels[cidx[cc1][cc2] - 1]); 2453a966c04fSmrg#else 2454a966c04fSmrg SelectObject(*dc, image->bitmap); 2455a966c04fSmrg SetPixel(*dc, x, y, image_pixels[cidx[cc1][cc2] - 1]); 2456a966c04fSmrg if (shapeimage) { 2457a966c04fSmrg SelectObject(*dc, shapeimage->bitmap); 2458a966c04fSmrg SetPixel(*dc, x, y, 2459a966c04fSmrg shape_pixels[cidx[cc1][cc2] - 1]); 2460a966c04fSmrg } 2461a966c04fSmrg#endif 2462a966c04fSmrg } else { 2463a966c04fSmrg FREE_CIDX; 2464a966c04fSmrg return (XpmFileInvalid); 2465a966c04fSmrg } 2466a966c04fSmrg } else { 2467a966c04fSmrg FREE_CIDX; 2468a966c04fSmrg return (XpmFileInvalid); 2469a966c04fSmrg } 2470a966c04fSmrg } 2471a966c04fSmrg } 2472a966c04fSmrg FREE_CIDX; 2473a966c04fSmrg } 2474a966c04fSmrg break; 2475a966c04fSmrg 2476a966c04fSmrg default: /* Non-optimized case of long color 2477a966c04fSmrg * names */ 2478a966c04fSmrg { 2479a966c04fSmrg char *s; 2480a966c04fSmrg char buf[BUFSIZ]; 2481a966c04fSmrg 2482a966c04fSmrg if (cpp >= sizeof(buf)) 2483a966c04fSmrg return (XpmFileInvalid); 2484a966c04fSmrg 2485a966c04fSmrg buf[cpp] = '\0'; 2486a966c04fSmrg if (USE_HASHTABLE) { 2487a966c04fSmrg xpmHashAtom *slot; 2488a966c04fSmrg 2489a966c04fSmrg for (y = 0; y < height; y++) { 2490a966c04fSmrg xpmNextString(data); 2491a966c04fSmrg for (x = 0; x < width; x++) { 2492a966c04fSmrg for (a = 0, s = buf; a < cpp; a++, s++) 2493a966c04fSmrg *s = xpmGetC(data); 2494a966c04fSmrg slot = xpmHashSlot(hashtable, buf); 2495a966c04fSmrg if (!*slot) /* no color matches */ 2496a966c04fSmrg return (XpmFileInvalid); 2497a966c04fSmrg#ifndef FOR_MSW 2498a966c04fSmrg XPutPixel(image, x, y, 2499a966c04fSmrg image_pixels[HashColorIndex(slot)]); 2500a966c04fSmrg if (shapeimage) 2501a966c04fSmrg XPutPixel(shapeimage, x, y, 2502a966c04fSmrg shape_pixels[HashColorIndex(slot)]); 2503a966c04fSmrg#else 2504a966c04fSmrg SelectObject(*dc, image->bitmap); 2505a966c04fSmrg SetPixel(*dc, x, y, 2506a966c04fSmrg image_pixels[HashColorIndex(slot)]); 2507a966c04fSmrg if (shapeimage) { 2508a966c04fSmrg SelectObject(*dc, shapeimage->bitmap); 2509a966c04fSmrg SetPixel(*dc, x, y, 2510a966c04fSmrg shape_pixels[HashColorIndex(slot)]); 2511a966c04fSmrg } 2512a966c04fSmrg#endif 2513a966c04fSmrg } 2514a966c04fSmrg } 2515a966c04fSmrg } else { 2516a966c04fSmrg for (y = 0; y < height; y++) { 2517a966c04fSmrg xpmNextString(data); 2518a966c04fSmrg for (x = 0; x < width; x++) { 2519a966c04fSmrg for (a = 0, s = buf; a < cpp; a++, s++) 2520a966c04fSmrg *s = xpmGetC(data); 2521a966c04fSmrg for (a = 0; a < ncolors; a++) 2522a966c04fSmrg if (!strcmp(colorTable[a].string, buf)) 2523a966c04fSmrg break; 2524a966c04fSmrg if (a == ncolors) /* no color matches */ 2525a966c04fSmrg return (XpmFileInvalid); 2526a966c04fSmrg#ifndef FOR_MSW 2527a966c04fSmrg XPutPixel(image, x, y, image_pixels[a]); 2528a966c04fSmrg if (shapeimage) 2529a966c04fSmrg XPutPixel(shapeimage, x, y, shape_pixels[a]); 2530a966c04fSmrg#else 2531a966c04fSmrg SelectObject(*dc, image->bitmap); 2532a966c04fSmrg SetPixel(*dc, x, y, image_pixels[a]); 2533a966c04fSmrg if (shapeimage) { 2534a966c04fSmrg SelectObject(*dc, shapeimage->bitmap); 2535a966c04fSmrg SetPixel(*dc, x, y, shape_pixels[a]); 2536a966c04fSmrg } 2537a966c04fSmrg#endif 2538a966c04fSmrg } 2539a966c04fSmrg } 2540a966c04fSmrg } 2541a966c04fSmrg } 2542a966c04fSmrg break; 2543a966c04fSmrg } 2544a966c04fSmrg return (XpmSuccess); 2545a966c04fSmrg} 2546