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