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