create.c revision c378da89
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 *image_return = NULL; 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 XDestroyImage(*image_return); 1003 *image_return = NULL; 1004 return XpmNoMemory; 1005 } 1006 (*image_return)->data = 1007 (char *) XpmMalloc((*image_return)->bytes_per_line * height); 1008 1009 if (!(*image_return)->data) { 1010 XDestroyImage(*image_return); 1011 *image_return = NULL; 1012 return (XpmNoMemory); 1013 } 1014#else 1015 /* under FOR_MSW and AMIGA XCreateImage has done it all */ 1016#endif 1017 return (XpmSuccess); 1018} 1019 1020#ifndef FOR_MSW 1021# ifndef AMIGA 1022/* 1023 * The functions below are written from X11R5 MIT's code (XImUtil.c) 1024 * 1025 * The idea is to have faster functions than the standard XPutPixel function 1026 * to build the image data. Indeed we can speed up things by suppressing tests 1027 * performed for each pixel. We do the same tests but at the image level. 1028 * We also assume that we use only ZPixmap images with null offsets. 1029 */ 1030 1031LFUNC(_putbits, void, (register char *src, int dstoffset, 1032 register int numbits, register char *dst)); 1033 1034LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register unsigned int nb)); 1035 1036static unsigned char const _reverse_byte[0x100] = { 1037 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 1038 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 1039 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 1040 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 1041 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 1042 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 1043 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 1044 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 1045 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 1046 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 1047 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 1048 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 1049 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 1050 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 1051 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 1052 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 1053 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 1054 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 1055 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 1056 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 1057 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 1058 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 1059 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 1060 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 1061 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 1062 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 1063 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 1064 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 1065 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 1066 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 1067 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 1068 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff 1069}; 1070 1071static int 1072_XReverse_Bytes( 1073 register unsigned char *bpt, 1074 register unsigned int nb) 1075{ 1076 do { 1077 *bpt = _reverse_byte[*bpt]; 1078 bpt++; 1079 } while (--nb > 0); /* is nb user-controled? */ 1080 return 0; 1081} 1082 1083 1084void 1085xpm_xynormalizeimagebits( 1086 register unsigned char *bp, 1087 register XImage *img) 1088{ 1089 register unsigned char c; 1090 1091 if (img->byte_order != img->bitmap_bit_order) { 1092 switch (img->bitmap_unit) { 1093 1094 case 16: 1095 c = *bp; 1096 *bp = *(bp + 1); 1097 *(bp + 1) = c; 1098 break; 1099 1100 case 32: 1101 c = *(bp + 3); 1102 *(bp + 3) = *bp; 1103 *bp = c; 1104 c = *(bp + 2); 1105 *(bp + 2) = *(bp + 1); 1106 *(bp + 1) = c; 1107 break; 1108 } 1109 } 1110 if (img->bitmap_bit_order == MSBFirst) 1111 _XReverse_Bytes(bp, img->bitmap_unit >> 3); 1112} 1113 1114void 1115xpm_znormalizeimagebits( 1116 register unsigned char *bp, 1117 register XImage *img) 1118{ 1119 register unsigned char c; 1120 1121 switch (img->bits_per_pixel) { 1122 1123 case 2: 1124 _XReverse_Bytes(bp, 1); 1125 break; 1126 1127 case 4: 1128 *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF); 1129 break; 1130 1131 case 16: 1132 c = *bp; 1133 *bp = *(bp + 1); 1134 *(bp + 1) = c; 1135 break; 1136 1137 case 24: 1138 c = *(bp + 2); 1139 *(bp + 2) = *bp; 1140 *bp = c; 1141 break; 1142 1143 case 32: 1144 c = *(bp + 3); 1145 *(bp + 3) = *bp; 1146 *bp = c; 1147 c = *(bp + 2); 1148 *(bp + 2) = *(bp + 1); 1149 *(bp + 1) = c; 1150 break; 1151 } 1152} 1153 1154static unsigned char const _lomask[0x09] = { 11550x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; 1156static unsigned char const _himask[0x09] = { 11570xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00}; 1158 1159static void 1160_putbits( 1161 register char *src, /* address of source bit string */ 1162 int dstoffset, /* bit offset into destination; 1163 * range is 0-31 */ 1164 register int numbits, /* number of bits to copy to 1165 * destination */ 1166 register char *dst) /* address of destination bit string */ 1167{ 1168 register unsigned char chlo, chhi; 1169 int hibits; 1170 1171 dst = dst + (dstoffset >> 3); 1172 dstoffset = dstoffset & 7; 1173 hibits = 8 - dstoffset; 1174 chlo = *dst & _lomask[dstoffset]; 1175 for (;;) { 1176 chhi = (*src << dstoffset) & _himask[dstoffset]; 1177 if (numbits <= hibits) { 1178 chhi = chhi & _lomask[dstoffset + numbits]; 1179 *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi; 1180 break; 1181 } 1182 *dst = chhi | chlo; 1183 dst++; 1184 numbits = numbits - hibits; 1185 chlo = (unsigned char) (*src & _himask[hibits]) >> hibits; 1186 src++; 1187 if (numbits <= dstoffset) { 1188 chlo = chlo & _lomask[numbits]; 1189 *dst = (*dst & _himask[numbits]) | chlo; 1190 break; 1191 } 1192 numbits = numbits - dstoffset; 1193 } 1194} 1195 1196/* 1197 * Default method to write pixels into a Z image data structure. 1198 * The algorithm used is: 1199 * 1200 * copy the destination bitmap_unit or Zpixel to temp 1201 * normalize temp if needed 1202 * copy the pixel bits into the temp 1203 * renormalize temp if needed 1204 * copy the temp back into the destination image data 1205 */ 1206 1207static void 1208PutImagePixels( 1209 XImage *image, 1210 unsigned int width, 1211 unsigned int height, 1212 unsigned int *pixelindex, 1213 Pixel *pixels) 1214{ 1215 register char *src; 1216 register char *dst; 1217 register unsigned int *iptr; 1218 register unsigned int x, y; 1219 register char *data; 1220 Pixel pixel, px; 1221 int nbytes, depth, ibu, ibpp, i; 1222 1223 data = image->data; 1224 iptr = pixelindex; 1225 depth = image->depth; 1226 if (depth == 1) { 1227 ibu = image->bitmap_unit; 1228 for (y = 0; y < height; y++) /* how can we trust height */ 1229 for (x = 0; x < width; x++, iptr++) { /* how can we trust width */ 1230 pixel = pixels[*iptr]; 1231 for (i = 0, px = pixel; i < sizeof(unsigned long); 1232 i++, px >>= 8) 1233 ((unsigned char *) &pixel)[i] = px; 1234 src = &data[XYINDEX(x, y, image)]; 1235 dst = (char *) &px; 1236 px = 0; 1237 nbytes = ibu >> 3; 1238 for (i = nbytes; --i >= 0;) 1239 *dst++ = *src++; 1240 XYNORMALIZE(&px, image); 1241 _putbits((char *) &pixel, (x % ibu), 1, (char *) &px); 1242 XYNORMALIZE(&px, image); 1243 src = (char *) &px; 1244 dst = &data[XYINDEX(x, y, image)]; 1245 for (i = nbytes; --i >= 0;) 1246 *dst++ = *src++; 1247 } 1248 } else { 1249 ibpp = image->bits_per_pixel; 1250 for (y = 0; y < height; y++) 1251 for (x = 0; x < width; x++, iptr++) { 1252 pixel = pixels[*iptr]; 1253 if (depth == 4) 1254 pixel &= 0xf; 1255 for (i = 0, px = pixel; i < sizeof(unsigned long); i++, 1256 px >>= 8) 1257 ((unsigned char *) &pixel)[i] = px; 1258 src = &data[ZINDEX(x, y, image)]; 1259 dst = (char *) &px; 1260 px = 0; 1261 nbytes = (ibpp + 7) >> 3; 1262 for (i = nbytes; --i >= 0;) 1263 *dst++ = *src++; 1264 ZNORMALIZE(&px, image); 1265 _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px); 1266 ZNORMALIZE(&px, image); 1267 src = (char *) &px; 1268 dst = &data[ZINDEX(x, y, image)]; 1269 for (i = nbytes; --i >= 0;) 1270 *dst++ = *src++; 1271 } 1272 } 1273} 1274 1275/* 1276 * write pixels into a 32-bits Z image data structure 1277 */ 1278 1279#if !defined(WORD64) && !defined(LONG64) 1280/* this item is static but deterministic so let it slide; doesn't 1281 * hurt re-entrancy of this library. Note if it is actually const then would 1282 * be OK under rules of ANSI-C but probably not C++ which may not 1283 * want to allocate space for it. 1284 */ 1285static unsigned long byteorderpixel = MSBFirst << 24; 1286 1287#endif 1288 1289/* 1290 WITHOUT_SPEEDUPS is a flag to be turned on if you wish to use the original 1291 3.2e code - by default you get the speeded-up version. 1292*/ 1293 1294static void 1295PutImagePixels32( 1296 XImage *image, 1297 unsigned int width, 1298 unsigned int height, 1299 unsigned int *pixelindex, 1300 Pixel *pixels) 1301{ 1302 unsigned char *data; 1303 unsigned int *iptr; 1304 unsigned int y; 1305 Pixel pixel; 1306 1307#ifdef WITHOUT_SPEEDUPS 1308 1309 unsigned int x; 1310 unsigned char *addr; 1311 1312 data = (unsigned char *) image->data; 1313 iptr = pixelindex; 1314#if !defined(WORD64) && !defined(LONG64) 1315 if (*((char *) &byteorderpixel) == image->byte_order) { 1316 for (y = 0; y < height; y++) 1317 for (x = 0; x < width; x++, iptr++) { 1318 addr = &data[ZINDEX32(x, y, image)]; 1319 *((unsigned long *) addr) = pixels[*iptr]; 1320 } 1321 } else 1322#endif 1323 if (image->byte_order == MSBFirst) 1324 for (y = 0; y < height; y++) 1325 for (x = 0; x < width; x++, iptr++) { 1326 addr = &data[ZINDEX32(x, y, image)]; 1327 pixel = pixels[*iptr]; 1328 addr[0] = pixel >> 24; 1329 addr[1] = pixel >> 16; 1330 addr[2] = pixel >> 8; 1331 addr[3] = pixel; 1332 } 1333 else 1334 for (y = 0; y < height; y++) 1335 for (x = 0; x < width; x++, iptr++) { 1336 addr = &data[ZINDEX32(x, y, image)]; 1337 pixel = pixels[*iptr]; 1338 addr[0] = pixel; 1339 addr[1] = pixel >> 8; 1340 addr[2] = pixel >> 16; 1341 addr[3] = pixel >> 24; 1342 } 1343 1344#else /* WITHOUT_SPEEDUPS */ 1345 1346 unsigned int bpl = image->bytes_per_line; 1347 unsigned char *data_ptr, *max_data; 1348 1349 data = (unsigned char *) image->data; 1350 iptr = pixelindex; 1351#if !defined(WORD64) && !defined(LONG64) 1352 if (*((char *) &byteorderpixel) == image->byte_order) { 1353 for (y = 0; y < height; y++) { 1354 data_ptr = data; 1355 max_data = data_ptr + (width << 2); 1356 1357 while (data_ptr < max_data) { 1358 *((unsigned long *) data_ptr) = pixels[*(iptr++)]; 1359 data_ptr += (1 << 2); 1360 } 1361 data += bpl; 1362 } 1363 } else 1364#endif 1365 if (image->byte_order == MSBFirst) 1366 for (y = 0; y < height; y++) { 1367 data_ptr = data; 1368 max_data = data_ptr + (width << 2); 1369 1370 while (data_ptr < max_data) { 1371 pixel = pixels[*(iptr++)]; 1372 1373 *data_ptr++ = pixel >> 24; 1374 *data_ptr++ = pixel >> 16; 1375 *data_ptr++ = pixel >> 8; 1376 *data_ptr++ = pixel; 1377 1378 } 1379 data += bpl; 1380 } 1381 else 1382 for (y = 0; y < height; y++) { 1383 data_ptr = data; 1384 max_data = data_ptr + (width << 2); 1385 1386 while (data_ptr < max_data) { 1387 pixel = pixels[*(iptr++)]; 1388 1389 *data_ptr++ = pixel; 1390 *data_ptr++ = pixel >> 8; 1391 *data_ptr++ = pixel >> 16; 1392 *data_ptr++ = pixel >> 24; 1393 } 1394 data += bpl; 1395 } 1396 1397#endif /* WITHOUT_SPEEDUPS */ 1398} 1399 1400/* 1401 * write pixels into a 16-bits Z image data structure 1402 */ 1403 1404static void 1405PutImagePixels16( 1406 XImage *image, 1407 unsigned int width, 1408 unsigned int height, 1409 unsigned int *pixelindex, 1410 Pixel *pixels) 1411{ 1412 unsigned char *data; 1413 unsigned int *iptr; 1414 unsigned int y; 1415 1416#ifdef WITHOUT_SPEEDUPS 1417 1418 unsigned int x; 1419 unsigned char *addr; 1420 1421 data = (unsigned char *) image->data; 1422 iptr = pixelindex; 1423 if (image->byte_order == MSBFirst) 1424 for (y = 0; y < height; y++) 1425 for (x = 0; x < width; x++, iptr++) { 1426 addr = &data[ZINDEX16(x, y, image)]; 1427 addr[0] = pixels[*iptr] >> 8; 1428 addr[1] = pixels[*iptr]; 1429 } 1430 else 1431 for (y = 0; y < height; y++) 1432 for (x = 0; x < width; x++, iptr++) { 1433 addr = &data[ZINDEX16(x, y, image)]; 1434 addr[0] = pixels[*iptr]; 1435 addr[1] = pixels[*iptr] >> 8; 1436 } 1437 1438#else /* WITHOUT_SPEEDUPS */ 1439 1440 Pixel pixel; 1441 1442 unsigned int bpl = image->bytes_per_line; 1443 unsigned char *data_ptr, *max_data; 1444 1445 data = (unsigned char *) image->data; 1446 iptr = pixelindex; 1447 if (image->byte_order == MSBFirst) 1448 for (y = 0; y < height; y++) { 1449 data_ptr = data; 1450 max_data = data_ptr + (width << 1); 1451 1452 while (data_ptr < max_data) { 1453 pixel = pixels[*(iptr++)]; 1454 1455 data_ptr[0] = pixel >> 8; 1456 data_ptr[1] = pixel; 1457 1458 data_ptr += (1 << 1); 1459 } 1460 data += bpl; 1461 } 1462 else 1463 for (y = 0; y < height; y++) { 1464 data_ptr = data; 1465 max_data = data_ptr + (width << 1); 1466 1467 while (data_ptr < max_data) { 1468 pixel = pixels[*(iptr++)]; 1469 1470 data_ptr[0] = pixel; 1471 data_ptr[1] = pixel >> 8; 1472 1473 data_ptr += (1 << 1); 1474 } 1475 data += bpl; 1476 } 1477 1478#endif /* WITHOUT_SPEEDUPS */ 1479} 1480 1481/* 1482 * write pixels into a 8-bits Z image data structure 1483 */ 1484 1485static void 1486PutImagePixels8( 1487 XImage *image, 1488 unsigned int width, 1489 unsigned int height, 1490 unsigned int *pixelindex, 1491 Pixel *pixels) 1492{ 1493 char *data; 1494 unsigned int *iptr; 1495 unsigned int y; 1496 1497#ifdef WITHOUT_SPEEDUPS 1498 1499 unsigned int x; 1500 1501 data = image->data; 1502 iptr = pixelindex; 1503 for (y = 0; y < height; y++) 1504 for (x = 0; x < width; x++, iptr++) 1505 data[ZINDEX8(x, y, image)] = pixels[*iptr]; 1506 1507#else /* WITHOUT_SPEEDUPS */ 1508 1509 unsigned int bpl = image->bytes_per_line; 1510 char *data_ptr, *max_data; 1511 1512 data = image->data; 1513 iptr = pixelindex; 1514 1515 for (y = 0; y < height; y++) { 1516 data_ptr = data; 1517 max_data = data_ptr + width; 1518 1519 while (data_ptr < max_data) 1520 *(data_ptr++) = pixels[*(iptr++)]; 1521 1522 data += bpl; 1523 } 1524 1525#endif /* WITHOUT_SPEEDUPS */ 1526} 1527 1528/* 1529 * write pixels into a 1-bit depth image data structure and **offset null** 1530 */ 1531 1532static void 1533PutImagePixels1( 1534 XImage *image, 1535 unsigned int width, 1536 unsigned int height, 1537 unsigned int *pixelindex, 1538 Pixel *pixels) 1539{ 1540 if (image->byte_order != image->bitmap_bit_order) 1541 PutImagePixels(image, width, height, pixelindex, pixels); 1542 else { 1543 unsigned int *iptr; 1544 unsigned int y; 1545 char *data; 1546 1547#ifdef WITHOUT_SPEEDUPS 1548 1549 unsigned int x; 1550 1551 data = image->data; 1552 iptr = pixelindex; 1553 if (image->bitmap_bit_order == MSBFirst) 1554 for (y = 0; y < height; y++) 1555 for (x = 0; x < width; x++, iptr++) { 1556 if (pixels[*iptr] & 1) 1557 data[ZINDEX1(x, y, image)] |= 0x80 >> (x & 7); 1558 else 1559 data[ZINDEX1(x, y, image)] &= ~(0x80 >> (x & 7)); 1560 } 1561 else 1562 for (y = 0; y < height; y++) 1563 for (x = 0; x < width; x++, iptr++) { 1564 if (pixels[*iptr] & 1) 1565 data[ZINDEX1(x, y, image)] |= 1 << (x & 7); 1566 else 1567 data[ZINDEX1(x, y, image)] &= ~(1 << (x & 7)); 1568 } 1569 1570#else /* WITHOUT_SPEEDUPS */ 1571 1572 char value; 1573 char *data_ptr, *max_data; 1574 int bpl = image->bytes_per_line; 1575 int diff, count; 1576 1577 data = image->data; 1578 iptr = pixelindex; 1579 1580 diff = width & 7; 1581 width >>= 3; 1582 1583 if (image->bitmap_bit_order == MSBFirst) 1584 for (y = 0; y < height; y++) { 1585 data_ptr = data; 1586 max_data = data_ptr + width; 1587 while (data_ptr < max_data) { 1588 value = 0; 1589 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 value = (value << 1) | (pixels[*(iptr++)] & 1); 1596 value = (value << 1) | (pixels[*(iptr++)] & 1); 1597 value = (value << 1) | (pixels[*(iptr++)] & 1); 1598 1599 *(data_ptr++) = value; 1600 } 1601 if (diff) { 1602 value = 0; 1603 for (count = 0; count < diff; count++) { 1604 if (pixels[*(iptr++)] & 1) 1605 value |= (0x80 >> count); 1606 } 1607 *(data_ptr) = value; 1608 } 1609 data += bpl; 1610 } 1611 else 1612 for (y = 0; y < height; y++) { 1613 data_ptr = data; 1614 max_data = data_ptr + width; 1615 while (data_ptr < max_data) { 1616 value = 0; 1617 iptr += 8; 1618 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 value = (value << 1) | (pixels[*(--iptr)] & 1); 1625 value = (value << 1) | (pixels[*(--iptr)] & 1); 1626 value = (value << 1) | (pixels[*(--iptr)] & 1); 1627 1628 iptr += 8; 1629 *(data_ptr++) = value; 1630 } 1631 if (diff) { 1632 value = 0; 1633 for (count = 0; count < diff; count++) { 1634 if (pixels[*(iptr++)] & 1) 1635 value |= (1 << count); 1636 } 1637 *(data_ptr) = value; 1638 } 1639 data += bpl; 1640 } 1641 1642#endif /* WITHOUT_SPEEDUPS */ 1643 } 1644} 1645 1646int 1647XpmCreatePixmapFromXpmImage( 1648 Display *display, 1649 Drawable d, 1650 XpmImage *image, 1651 Pixmap *pixmap_return, 1652 Pixmap *shapemask_return, 1653 XpmAttributes *attributes) 1654{ 1655 XImage *ximage, *shapeimage; 1656 int ErrorStatus; 1657 1658 /* initialize return values */ 1659 if (pixmap_return) 1660 *pixmap_return = 0; 1661 if (shapemask_return) 1662 *shapemask_return = 0; 1663 1664 /* create the ximages */ 1665 ErrorStatus = XpmCreateImageFromXpmImage(display, image, 1666 (pixmap_return ? &ximage : NULL), 1667 (shapemask_return ? 1668 &shapeimage : NULL), 1669 attributes); 1670 if (ErrorStatus < 0) 1671 return (ErrorStatus); 1672 1673 /* create the pixmaps and destroy images */ 1674 if (pixmap_return && ximage) { 1675 xpmCreatePixmapFromImage(display, d, ximage, pixmap_return); 1676 XDestroyImage(ximage); 1677 } 1678 if (shapemask_return && shapeimage) { 1679 xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return); 1680 XDestroyImage(shapeimage); 1681 } 1682 return (ErrorStatus); 1683} 1684 1685# else /* AMIGA */ 1686 1687static void 1688APutImagePixels ( 1689 XImage *image, 1690 unsigned int width, 1691 unsigned int height, 1692 unsigned int *pixelindex, 1693 Pixel *pixels) 1694{ 1695 unsigned int *data = pixelindex; 1696 unsigned int x, y; 1697 unsigned char *array; 1698 XImage *tmp_img; 1699 BOOL success = FALSE; 1700 1701 array = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*array)); 1702 if (array != NULL) 1703 { 1704 tmp_img = AllocXImage ((((width+15)>>4)<<4), 1, 1705 image->rp->BitMap->Depth); 1706 if (tmp_img != NULL) 1707 { 1708 for (y = 0; y < height; ++y) 1709 { 1710 for (x = 0; x < width; ++x) 1711 array[x] = pixels[*(data++)]; 1712 WritePixelLine8 (image->rp, 0, y, width, array, tmp_img->rp); 1713 } 1714 FreeXImage (tmp_img); 1715 success = TRUE; 1716 } 1717 XpmFree (array); 1718 } 1719 1720 if (!success) 1721 { 1722 for (y = 0; y < height; ++y) 1723 for (x = 0; x < width; ++x) 1724 XPutPixel (image, x, y, pixels[*(data++)]); 1725 } 1726} 1727 1728# endif/* AMIGA */ 1729#else /* FOR_MSW part follows */ 1730static void 1731MSWPutImagePixels( 1732 Display *dc, 1733 XImage *image, 1734 unsigned int width, 1735 unsigned int height, 1736 unsigned int *pixelindex, 1737 Pixel *pixels) 1738{ 1739 unsigned int *data = pixelindex; 1740 unsigned int x, y; 1741 HBITMAP obm; 1742 1743 obm = SelectObject(*dc, image->bitmap); 1744 for (y = 0; y < height; y++) { 1745 for (x = 0; x < width; x++) { 1746 SetPixel(*dc, x, y, pixels[*(data++)]); /* data is [x+y*width] */ 1747 } 1748 } 1749 SelectObject(*dc, obm); 1750} 1751 1752#endif /* FOR_MSW */ 1753 1754 1755 1756#if !defined(FOR_MSW) && !defined(AMIGA) 1757 1758static int 1759PutPixel1( 1760 register XImage *ximage, 1761 int x, 1762 int y, 1763 unsigned long pixel) 1764{ 1765 register char *src; 1766 register char *dst; 1767 register int i; 1768 Pixel px; 1769 int nbytes; 1770 1771 if(x < 0 || y < 0) 1772 return 0; 1773 1774 for (i=0, px=pixel; i<sizeof(unsigned long); i++, px>>=8) 1775 ((unsigned char *)&pixel)[i] = px; 1776 src = &ximage->data[XYINDEX(x, y, ximage)]; 1777 dst = (char *)&px; 1778 px = 0; 1779 nbytes = ximage->bitmap_unit >> 3; 1780 for (i = nbytes; --i >= 0; ) *dst++ = *src++; 1781 XYNORMALIZE(&px, ximage); 1782 i = ((x + ximage->xoffset) % ximage->bitmap_unit); 1783 _putbits ((char *)&pixel, i, 1, (char *)&px); 1784 XYNORMALIZE(&px, ximage); 1785 src = (char *) &px; 1786 dst = &ximage->data[XYINDEX(x, y, ximage)]; 1787 for (i = nbytes; --i >= 0; ) 1788 *dst++ = *src++; 1789 1790 return 1; 1791} 1792 1793static int 1794PutPixel( 1795 register XImage *ximage, 1796 int x, 1797 int y, 1798 unsigned long pixel) 1799{ 1800 register char *src; 1801 register char *dst; 1802 register int i; 1803 Pixel px; 1804 unsigned int nbytes, ibpp; 1805 1806 if(x < 0 || y < 0) 1807 return 0; 1808 1809 ibpp = ximage->bits_per_pixel; 1810 if (ximage->depth == 4) 1811 pixel &= 0xf; 1812 for (i = 0, px = pixel; i < sizeof(unsigned long); i++, px >>= 8) 1813 ((unsigned char *) &pixel)[i] = px; 1814 src = &ximage->data[ZINDEX(x, y, ximage)]; 1815 dst = (char *) &px; 1816 px = 0; 1817 nbytes = (ibpp + 7) >> 3; 1818 for (i = nbytes; --i >= 0;) 1819 *dst++ = *src++; 1820 ZNORMALIZE(&px, ximage); 1821 _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px); 1822 ZNORMALIZE(&px, ximage); 1823 src = (char *) &px; 1824 dst = &ximage->data[ZINDEX(x, y, ximage)]; 1825 for (i = nbytes; --i >= 0;) 1826 *dst++ = *src++; 1827 1828 return 1; 1829} 1830 1831#if !defined(WORD64) && !defined(LONG64) 1832static int 1833PutPixel32( 1834 register XImage *ximage, 1835 int x, 1836 int y, 1837 unsigned long pixel) 1838{ 1839 unsigned char *addr; 1840 1841 if(x < 0 || y < 0) 1842 return 0; 1843 1844 addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; 1845 *((unsigned long *)addr) = pixel; 1846 return 1; 1847} 1848#endif 1849 1850static int 1851PutPixel32MSB( 1852 register XImage *ximage, 1853 int x, 1854 int y, 1855 unsigned long pixel) 1856{ 1857 unsigned char *addr; 1858 1859 if(x < 0 || y < 0) 1860 return 0; 1861 1862 addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; 1863 addr[0] = pixel >> 24; 1864 addr[1] = pixel >> 16; 1865 addr[2] = pixel >> 8; 1866 addr[3] = pixel; 1867 return 1; 1868} 1869 1870static int 1871PutPixel32LSB( 1872 register XImage *ximage, 1873 int x, 1874 int y, 1875 unsigned long pixel) 1876{ 1877 unsigned char *addr; 1878 1879 if(x < 0 || y < 0) 1880 return 0; 1881 1882 addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; 1883 addr[3] = pixel >> 24; 1884 addr[2] = pixel >> 16; 1885 addr[1] = pixel >> 8; 1886 addr[0] = pixel; 1887 return 1; 1888} 1889 1890static int 1891PutPixel16MSB( 1892 register XImage *ximage, 1893 int x, 1894 int y, 1895 unsigned long pixel) 1896{ 1897 unsigned char *addr; 1898 1899 if(x < 0 || y < 0) 1900 return 0; 1901 1902 addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)]; 1903 addr[0] = pixel >> 8; 1904 addr[1] = pixel; 1905 return 1; 1906} 1907 1908static int 1909PutPixel16LSB( 1910 register XImage *ximage, 1911 int x, 1912 int y, 1913 unsigned long pixel) 1914{ 1915 unsigned char *addr; 1916 1917 if(x < 0 || y < 0) 1918 return 0; 1919 1920 addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)]; 1921 addr[1] = pixel >> 8; 1922 addr[0] = pixel; 1923 return 1; 1924} 1925 1926static int 1927PutPixel8( 1928 register XImage *ximage, 1929 int x, 1930 int y, 1931 unsigned long pixel) 1932{ 1933 if(x < 0 || y < 0) 1934 return 0; 1935 1936 ximage->data[ZINDEX8(x, y, ximage)] = pixel; 1937 return 1; 1938} 1939 1940static int 1941PutPixel1MSB( 1942 register XImage *ximage, 1943 int x, 1944 int y, 1945 unsigned long pixel) 1946{ 1947 if(x < 0 || y < 0) 1948 return 0; 1949 1950 if (pixel & 1) 1951 ximage->data[ZINDEX1(x, y, ximage)] |= 0x80 >> (x & 7); 1952 else 1953 ximage->data[ZINDEX1(x, y, ximage)] &= ~(0x80 >> (x & 7)); 1954 return 1; 1955} 1956 1957static int 1958PutPixel1LSB( 1959 register XImage *ximage, 1960 int x, 1961 int y, 1962 unsigned long pixel) 1963{ 1964 if(x < 0 || y < 0) 1965 return 0; 1966 1967 if (pixel & 1) 1968 ximage->data[ZINDEX1(x, y, ximage)] |= 1 << (x & 7); 1969 else 1970 ximage->data[ZINDEX1(x, y, ximage)] &= ~(1 << (x & 7)); 1971 return 1; 1972} 1973 1974#endif /* not FOR_MSW && not AMIGA */ 1975 1976/* 1977 * This function parses an Xpm file or data and directly create an XImage 1978 */ 1979int 1980xpmParseDataAndCreate( 1981 Display *display, 1982 xpmData *data, 1983 XImage **image_return, 1984 XImage **shapeimage_return, 1985 XpmImage *image, 1986 XpmInfo *info, 1987 XpmAttributes *attributes) 1988{ 1989 /* variables stored in the XpmAttributes structure */ 1990 Visual *visual; 1991 Colormap colormap; 1992 unsigned int depth; 1993 int bitmap_format; 1994 XpmFreeColorsFunc freeColors; 1995 1996 /* variables to return */ 1997 XImage *ximage = NULL; 1998 XImage *shapeimage = NULL; 1999 unsigned int mask_pixel_index = XpmUndefPixel; 2000 2001 /* calculation variables */ 2002 Pixel *image_pixels = NULL; 2003 Pixel *mask_pixels = NULL; 2004 Pixel *alloc_pixels = NULL; 2005 Pixel *used_pixels = NULL; 2006 unsigned int nalloc_pixels = 0; 2007 unsigned int nused_pixels = 0; 2008 unsigned int width, height, ncolors, cpp; 2009 unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0; 2010 XpmColor *colorTable = NULL; 2011 char *hints_cmt = NULL; 2012 char *colors_cmt = NULL; 2013 char *pixels_cmt = NULL; 2014 2015 unsigned int cmts; 2016 int ErrorStatus; 2017 xpmHashTable hashtable; 2018 2019 2020 /* initialize return values */ 2021 if (image_return) 2022 *image_return = NULL; 2023 if (shapeimage_return) 2024 *shapeimage_return = NULL; 2025 2026 2027 /* retrieve information from the XpmAttributes */ 2028 if (attributes && (attributes->valuemask & XpmVisual)) 2029 visual = attributes->visual; 2030 else 2031 visual = XDefaultVisual(display, XDefaultScreen(display)); 2032 2033 if (attributes && (attributes->valuemask & XpmColormap)) 2034 colormap = attributes->colormap; 2035 else 2036 colormap = XDefaultColormap(display, XDefaultScreen(display)); 2037 2038 if (attributes && (attributes->valuemask & XpmDepth)) 2039 depth = attributes->depth; 2040 else 2041 depth = XDefaultDepth(display, XDefaultScreen(display)); 2042 2043 if (attributes && (attributes->valuemask & XpmBitmapFormat)) 2044 bitmap_format = attributes->bitmap_format; 2045 else 2046 bitmap_format = ZPixmap; 2047 2048 if (attributes && (attributes->valuemask & XpmFreeColors)) 2049 freeColors = attributes->free_colors; 2050 else 2051 freeColors = FreeColors; 2052 2053 cmts = info && (info->valuemask & XpmReturnComments); 2054 2055 /* 2056 * parse the header 2057 */ 2058 ErrorStatus = xpmParseHeader(data); 2059 if (ErrorStatus != XpmSuccess) 2060 return (ErrorStatus); 2061 2062 /* 2063 * read values 2064 */ 2065 ErrorStatus = xpmParseValues(data, &width, &height, &ncolors, &cpp, 2066 &x_hotspot, &y_hotspot, &hotspot, 2067 &extensions); 2068 if (ErrorStatus != XpmSuccess) 2069 return (ErrorStatus); 2070 2071 /* 2072 * store the hints comment line 2073 */ 2074 if (cmts) 2075 xpmGetCmt(data, &hints_cmt); 2076 2077 /* 2078 * init the hashtable 2079 */ 2080 if (USE_HASHTABLE) { 2081 ErrorStatus = xpmHashTableInit(&hashtable); 2082 if (ErrorStatus != XpmSuccess) 2083 RETURN(ErrorStatus); 2084 } 2085 2086 /* 2087 * read colors 2088 */ 2089 ErrorStatus = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable); 2090 if (ErrorStatus != XpmSuccess) 2091 RETURN(ErrorStatus); 2092 2093 /* 2094 * store the colors comment line 2095 */ 2096 if (cmts) 2097 xpmGetCmt(data, &colors_cmt); 2098 2099 /* malloc pixels index tables */ 2100 if (ncolors >= UINT_MAX / sizeof(Pixel)) 2101 RETURN(XpmNoMemory); 2102 2103 image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); 2104 if (!image_pixels) 2105 RETURN(XpmNoMemory); 2106 2107 mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); 2108 if (!mask_pixels) 2109 RETURN(XpmNoMemory); 2110 2111 /* maximum of allocated pixels will be the number of colors */ 2112 alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); 2113 if (!alloc_pixels) 2114 RETURN(XpmNoMemory); 2115 2116 /* maximum of allocated pixels will be the number of colors */ 2117 used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); 2118 if (!used_pixels) 2119 RETURN(XpmNoMemory); 2120 2121 /* get pixel colors, store them in index tables */ 2122 ErrorStatus = CreateColors(display, attributes, colorTable, ncolors, 2123 image_pixels, mask_pixels, &mask_pixel_index, 2124 alloc_pixels, &nalloc_pixels, used_pixels, 2125 &nused_pixels); 2126 2127 if (ErrorStatus != XpmSuccess 2128 && (ErrorStatus < 0 || (attributes 2129 && (attributes->valuemask & XpmExactColors) 2130 && attributes->exactColors))) 2131 RETURN(ErrorStatus); 2132 2133 /* now create the ximage */ 2134 if (image_return) { 2135 ErrorStatus = CreateXImage(display, visual, depth, 2136 (depth == 1 ? bitmap_format : ZPixmap), 2137 width, height, &ximage); 2138 if (ErrorStatus != XpmSuccess) 2139 RETURN(ErrorStatus); 2140 2141#if !defined(FOR_MSW) && !defined(AMIGA) 2142 2143 /* 2144 * set the XImage pointer function, to be used with XPutPixel, 2145 * to an internal optimized function 2146 */ 2147 2148 if (ximage->bits_per_pixel == 8) 2149 ximage->f.put_pixel = PutPixel8; 2150 else if (((ximage->bits_per_pixel | ximage->depth) == 1) && 2151 (ximage->byte_order == ximage->bitmap_bit_order)) 2152 if (ximage->bitmap_bit_order == MSBFirst) 2153 ximage->f.put_pixel = PutPixel1MSB; 2154 else 2155 ximage->f.put_pixel = PutPixel1LSB; 2156 else if (ximage->bits_per_pixel == 16) 2157 if (ximage->bitmap_bit_order == MSBFirst) 2158 ximage->f.put_pixel = PutPixel16MSB; 2159 else 2160 ximage->f.put_pixel = PutPixel16LSB; 2161 else if (ximage->bits_per_pixel == 32) 2162#if !defined(WORD64) && !defined(LONG64) 2163 if (*((char *)&byteorderpixel) == ximage->byte_order) 2164 ximage->f.put_pixel = PutPixel32; 2165 else 2166#endif 2167 if (ximage->bitmap_bit_order == MSBFirst) 2168 ximage->f.put_pixel = PutPixel32MSB; 2169 else 2170 ximage->f.put_pixel = PutPixel32LSB; 2171 else if ((ximage->bits_per_pixel | ximage->depth) == 1) 2172 ximage->f.put_pixel = PutPixel1; 2173 else 2174 ximage->f.put_pixel = PutPixel; 2175#endif /* not FOR_MSW && not AMIGA */ 2176 } 2177 2178 /* create the shape mask image */ 2179 if (mask_pixel_index != XpmUndefPixel && shapeimage_return) { 2180 ErrorStatus = CreateXImage(display, visual, 1, bitmap_format, 2181 width, height, &shapeimage); 2182 if (ErrorStatus != XpmSuccess) 2183 RETURN(ErrorStatus); 2184 2185#if !defined(FOR_MSW) && !defined(AMIGA) 2186 if (shapeimage->bitmap_bit_order == MSBFirst) 2187 shapeimage->f.put_pixel = PutPixel1MSB; 2188 else 2189 shapeimage->f.put_pixel = PutPixel1LSB; 2190#endif 2191 } 2192 2193 /* 2194 * read pixels and put them in the XImage 2195 */ 2196 ErrorStatus = ParseAndPutPixels( 2197#ifdef FOR_MSW 2198 display, 2199#endif 2200 data, width, height, ncolors, cpp, 2201 colorTable, &hashtable, 2202 ximage, image_pixels, 2203 shapeimage, mask_pixels); 2204 XpmFree(image_pixels); 2205 image_pixels = NULL; 2206 XpmFree(mask_pixels); 2207 mask_pixels = NULL; 2208 2209 /* 2210 * free the hastable 2211 */ 2212 if (ErrorStatus != XpmSuccess) 2213 RETURN(ErrorStatus); 2214 else if (USE_HASHTABLE) 2215 xpmHashTableFree(&hashtable); 2216 2217 /* 2218 * store the pixels comment line 2219 */ 2220 if (cmts) 2221 xpmGetCmt(data, &pixels_cmt); 2222 2223 /* 2224 * parse extensions 2225 */ 2226 if (info && (info->valuemask & XpmReturnExtensions)) { 2227 if (extensions) { 2228 ErrorStatus = xpmParseExtensions(data, &info->extensions, 2229 &info->nextensions); 2230 if (ErrorStatus != XpmSuccess) 2231 RETURN(ErrorStatus); 2232 } else { 2233 info->extensions = NULL; 2234 info->nextensions = 0; 2235 } 2236 } 2237 /* 2238 * store found information in the XpmImage structure 2239 */ 2240 image->width = width; 2241 image->height = height; 2242 image->cpp = cpp; 2243 image->ncolors = ncolors; 2244 image->colorTable = colorTable; 2245 image->data = NULL; 2246 2247 if (info) { 2248 if (cmts) { 2249 info->hints_cmt = hints_cmt; 2250 info->colors_cmt = colors_cmt; 2251 info->pixels_cmt = pixels_cmt; 2252 } 2253 if (hotspot) { 2254 info->x_hotspot = x_hotspot; 2255 info->y_hotspot = y_hotspot; 2256 info->valuemask |= XpmHotspot; 2257 } 2258 } 2259 /* if requested return used pixels in the XpmAttributes structure */ 2260 if (attributes && (attributes->valuemask & XpmReturnPixels || 2261/* 3.2 backward compatibility code */ 2262 attributes->valuemask & XpmReturnInfos)) { 2263/* end 3.2 bc */ 2264 attributes->pixels = used_pixels; 2265 attributes->npixels = nused_pixels; 2266 attributes->mask_pixel = mask_pixel_index; 2267 } else 2268 XpmFree(used_pixels); 2269 2270 /* if requested return alloc'ed pixels in the XpmAttributes structure */ 2271 if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) { 2272 attributes->alloc_pixels = alloc_pixels; 2273 attributes->nalloc_pixels = nalloc_pixels; 2274 } else 2275 XpmFree(alloc_pixels); 2276 2277 /* return created images */ 2278 if (image_return) 2279 *image_return = ximage; 2280 if (shapeimage_return) 2281 *shapeimage_return = shapeimage; 2282 2283 return (XpmSuccess); 2284 2285/* exit point in case of error, free only locally allocated variables */ 2286error: 2287 if (USE_HASHTABLE) 2288 xpmHashTableFree(&hashtable); 2289 if (colorTable) 2290 xpmFreeColorTable(colorTable, ncolors); 2291 if (hints_cmt) 2292 XpmFree(hints_cmt); 2293 if (colors_cmt) 2294 XpmFree(colors_cmt); 2295 if (pixels_cmt) 2296 XpmFree(pixels_cmt); 2297 if (ximage) 2298 XDestroyImage(ximage); 2299 if (shapeimage) 2300 XDestroyImage(shapeimage); 2301 if (image_pixels) 2302 XpmFree(image_pixels); 2303 if (mask_pixels) 2304 XpmFree(mask_pixels); 2305 if (nalloc_pixels) 2306 (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL); 2307 if (alloc_pixels) 2308 XpmFree(alloc_pixels); 2309 if (used_pixels) 2310 XpmFree(used_pixels); 2311 2312 return (ErrorStatus); 2313} 2314 2315static int 2316ParseAndPutPixels( 2317#ifdef FOR_MSW 2318 Display *dc, 2319#endif 2320 xpmData *data, 2321 unsigned int width, 2322 unsigned int height, 2323 unsigned int ncolors, 2324 unsigned int cpp, 2325 XpmColor *colorTable, 2326 xpmHashTable *hashtable, 2327 XImage *image, 2328 Pixel *image_pixels, 2329 XImage *shapeimage, 2330 Pixel *shape_pixels) 2331{ 2332 unsigned int a, x, y; 2333 2334 switch (cpp) { 2335 2336 case (1): /* Optimize for single character 2337 * colors */ 2338 { 2339 unsigned short colidx[256]; 2340#ifdef FOR_MSW 2341 HDC shapedc; 2342 HBITMAP obm, sobm; 2343 2344 if ( shapeimage ) { 2345 shapedc = CreateCompatibleDC(*dc); 2346 sobm = SelectObject(shapedc, shapeimage->bitmap); 2347 } else { 2348 shapedc = NULL; 2349 } 2350 obm = SelectObject(*dc, image->bitmap); 2351#endif 2352 if (ncolors > 256) 2353 return (XpmFileInvalid); 2354 2355 bzero((char *)colidx, 256 * sizeof(short)); 2356 for (a = 0; a < ncolors; a++) 2357 colidx[(unsigned char)colorTable[a].string[0]] = a + 1; 2358 2359 for (y = 0; y < height; y++) { 2360 xpmNextString(data); 2361 for (x = 0; x < width; x++) { 2362 int c = xpmGetC(data); 2363 2364 if (c > 0 && c < 256 && colidx[c] != 0) { 2365#ifndef FOR_MSW 2366 XPutPixel(image, x, y, image_pixels[colidx[c] - 1]); 2367 if (shapeimage) 2368 XPutPixel(shapeimage, x, y, 2369 shape_pixels[colidx[c] - 1]); 2370#else 2371 SetPixel(*dc, x, y, image_pixels[colidx[c] - 1]); 2372 if (shapedc) { 2373 SetPixel(shapedc, x, y, shape_pixels[colidx[c] - 1]); 2374 } 2375#endif 2376 } else 2377 return (XpmFileInvalid); 2378 } 2379 } 2380#ifdef FOR_MSW 2381 if ( shapedc ) { 2382 SelectObject(shapedc, sobm); 2383 DeleteDC(shapedc); 2384 } 2385 SelectObject(*dc, obm); 2386#endif 2387 } 2388 break; 2389 2390 case (2): /* Optimize for double character 2391 * colors */ 2392 { 2393 2394/* free all allocated pointers at all exits */ 2395#define FREE_CIDX {int f; for (f = 0; f < 256; f++) \ 2396if (cidx[f]) XpmFree(cidx[f]);} 2397 2398 /* array of pointers malloced by need */ 2399 unsigned short *cidx[256]; 2400 unsigned int char1; 2401 2402 bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */ 2403 for (a = 0; a < ncolors; a++) { 2404 char1 = (unsigned char) colorTable[a].string[0]; 2405 if (cidx[char1] == NULL) { /* get new memory */ 2406 cidx[char1] = (unsigned short *) 2407 XpmCalloc(256, sizeof(unsigned short)); 2408 if (cidx[char1] == NULL) { /* new block failed */ 2409 FREE_CIDX; 2410 return (XpmNoMemory); 2411 } 2412 } 2413 cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1; 2414 } 2415 2416 for (y = 0; y < height; y++) { 2417 xpmNextString(data); 2418 for (x = 0; x < width; x++) { 2419 int cc1 = xpmGetC(data); 2420 if (cc1 > 0 && cc1 < 256) { 2421 int cc2 = xpmGetC(data); 2422 if (cc2 > 0 && cc2 < 256 && 2423 cidx[cc1] && cidx[cc1][cc2] != 0) { 2424#ifndef FOR_MSW 2425 XPutPixel(image, x, y, 2426 image_pixels[cidx[cc1][cc2] - 1]); 2427 if (shapeimage) 2428 XPutPixel(shapeimage, x, y, 2429 shape_pixels[cidx[cc1][cc2] - 1]); 2430#else 2431 SelectObject(*dc, image->bitmap); 2432 SetPixel(*dc, x, y, image_pixels[cidx[cc1][cc2] - 1]); 2433 if (shapeimage) { 2434 SelectObject(*dc, shapeimage->bitmap); 2435 SetPixel(*dc, x, y, 2436 shape_pixels[cidx[cc1][cc2] - 1]); 2437 } 2438#endif 2439 } else { 2440 FREE_CIDX; 2441 return (XpmFileInvalid); 2442 } 2443 } else { 2444 FREE_CIDX; 2445 return (XpmFileInvalid); 2446 } 2447 } 2448 } 2449 FREE_CIDX; 2450 } 2451 break; 2452 2453 default: /* Non-optimized case of long color 2454 * names */ 2455 { 2456 char *s; 2457 char buf[BUFSIZ]; 2458 2459 if (cpp >= sizeof(buf)) 2460 return (XpmFileInvalid); 2461 2462 buf[cpp] = '\0'; 2463 if (USE_HASHTABLE) { 2464 xpmHashAtom *slot; 2465 2466 for (y = 0; y < height; y++) { 2467 xpmNextString(data); 2468 for (x = 0; x < width; x++) { 2469 for (a = 0, s = buf; a < cpp; a++, s++) 2470 *s = xpmGetC(data); 2471 slot = xpmHashSlot(hashtable, buf); 2472 if (!*slot) /* no color matches */ 2473 return (XpmFileInvalid); 2474#ifndef FOR_MSW 2475 XPutPixel(image, x, y, 2476 image_pixels[HashColorIndex(slot)]); 2477 if (shapeimage) 2478 XPutPixel(shapeimage, x, y, 2479 shape_pixels[HashColorIndex(slot)]); 2480#else 2481 SelectObject(*dc, image->bitmap); 2482 SetPixel(*dc, x, y, 2483 image_pixels[HashColorIndex(slot)]); 2484 if (shapeimage) { 2485 SelectObject(*dc, shapeimage->bitmap); 2486 SetPixel(*dc, x, y, 2487 shape_pixels[HashColorIndex(slot)]); 2488 } 2489#endif 2490 } 2491 } 2492 } else { 2493 for (y = 0; y < height; y++) { 2494 xpmNextString(data); 2495 for (x = 0; x < width; x++) { 2496 for (a = 0, s = buf; a < cpp; a++, s++) 2497 *s = xpmGetC(data); 2498 for (a = 0; a < ncolors; a++) 2499 if (!strcmp(colorTable[a].string, buf)) 2500 break; 2501 if (a == ncolors) /* no color matches */ 2502 return (XpmFileInvalid); 2503#ifndef FOR_MSW 2504 XPutPixel(image, x, y, image_pixels[a]); 2505 if (shapeimage) 2506 XPutPixel(shapeimage, x, y, shape_pixels[a]); 2507#else 2508 SelectObject(*dc, image->bitmap); 2509 SetPixel(*dc, x, y, image_pixels[a]); 2510 if (shapeimage) { 2511 SelectObject(*dc, shapeimage->bitmap); 2512 SetPixel(*dc, x, y, shape_pixels[a]); 2513 } 2514#endif 2515 } 2516 } 2517 } 2518 } 2519 break; 2520 } 2521 return (XpmSuccess); 2522} 2523