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