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