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