1a966c04fSmrg/* 2a966c04fSmrg * Copyright (C) 1989-95 GROUPE BULL 3a966c04fSmrg * 4a966c04fSmrg * Permission is hereby granted, free of charge, to any person obtaining a copy 5a966c04fSmrg * of this software and associated documentation files (the "Software"), to 6a966c04fSmrg * deal in the Software without restriction, including without limitation the 7a966c04fSmrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8a966c04fSmrg * sell copies of the Software, and to permit persons to whom the Software is 9a966c04fSmrg * furnished to do so, subject to the following conditions: 10a966c04fSmrg * 11a966c04fSmrg * The above copyright notice and this permission notice shall be included in 12a966c04fSmrg * all copies or substantial portions of the Software. 13a966c04fSmrg * 14a966c04fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15a966c04fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16a966c04fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17a966c04fSmrg * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18a966c04fSmrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19a966c04fSmrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20a966c04fSmrg * 21a966c04fSmrg * Except as contained in this notice, the name of GROUPE BULL shall not be 22a966c04fSmrg * used in advertising or otherwise to promote the sale, use or other dealings 23a966c04fSmrg * in this Software without prior written authorization from GROUPE BULL. 24a966c04fSmrg */ 25a966c04fSmrg 26a966c04fSmrg/*****************************************************************************\ 27a966c04fSmrg* scan.c: * 28a966c04fSmrg* * 29a966c04fSmrg* XPM library * 30a966c04fSmrg* Scanning utility for XPM file format * 31a966c04fSmrg* * 32a966c04fSmrg* Developed by Arnaud Le Hors * 33a966c04fSmrg\*****************************************************************************/ 34a966c04fSmrg 35a966c04fSmrg/* 36a966c04fSmrg * The code related to FOR_MSW has been added by 37a966c04fSmrg * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 38a966c04fSmrg */ 39a966c04fSmrg 40a966c04fSmrg/* 41a966c04fSmrg * The code related to AMIGA has been added by 42a966c04fSmrg * Lorens Younes (d93-hyo@nada.kth.se) 4/96 43a966c04fSmrg */ 44a966c04fSmrg 45a966c04fSmrg/* October 2004, source code review by Thomas Biege <thomas@suse.de> */ 46a966c04fSmrg 47a966c04fSmrg#ifdef HAVE_CONFIG_H 48a966c04fSmrg#include <config.h> 49a966c04fSmrg#endif 50a966c04fSmrg#include "XpmI.h" 51a966c04fSmrg 52a966c04fSmrg#define MAXPRINTABLE 92 /* number of printable ascii chars 53a966c04fSmrg * minus \ and " for string compat 54a966c04fSmrg * and ? to avoid ANSI trigraphs. */ 55a966c04fSmrg 5697cf2ee2Smrgstatic const char *printable = 57a966c04fSmrg" .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\ 58a966c04fSmrgASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; 59a966c04fSmrg 60a966c04fSmrg/* 61a966c04fSmrg * printable begin with a space, so in most case, due to my algorithm, when 62a966c04fSmrg * the number of different colors is less than MAXPRINTABLE, it will give a 63a966c04fSmrg * char follow by "nothing" (a space) in the readable xpm file 64a966c04fSmrg */ 65a966c04fSmrg 66a966c04fSmrg 67a966c04fSmrgtypedef struct { 68a966c04fSmrg Pixel *pixels; 69a966c04fSmrg unsigned int *pixelindex; 70a966c04fSmrg unsigned int size; 71a966c04fSmrg unsigned int ncolors; 72a966c04fSmrg unsigned int mask_pixel; /* whether there is or not */ 73a966c04fSmrg} PixelsMap; 74a966c04fSmrg 75a966c04fSmrgLFUNC(storePixel, int, (Pixel pixel, PixelsMap *pmap, 76a966c04fSmrg unsigned int *index_return)); 77a966c04fSmrg 78a966c04fSmrgLFUNC(storeMaskPixel, int, (Pixel pixel, PixelsMap *pmap, 79a966c04fSmrg unsigned int *index_return)); 80a966c04fSmrg 81a966c04fSmrgtypedef int (*storeFuncPtr)(Pixel pixel, PixelsMap *pmap, 82a966c04fSmrg unsigned int *index_return); 83a966c04fSmrg 84a966c04fSmrg#ifndef FOR_MSW 85a966c04fSmrg# ifndef AMIGA 86a966c04fSmrgLFUNC(GetImagePixels, int, (XImage *image, unsigned int width, 87a966c04fSmrg unsigned int height, PixelsMap *pmap)); 88a966c04fSmrg 89a966c04fSmrgLFUNC(GetImagePixels32, int, (XImage *image, unsigned int width, 90a966c04fSmrg unsigned int height, PixelsMap *pmap)); 91a966c04fSmrg 92a966c04fSmrgLFUNC(GetImagePixels16, int, (XImage *image, unsigned int width, 93a966c04fSmrg unsigned int height, PixelsMap *pmap)); 94a966c04fSmrg 95a966c04fSmrgLFUNC(GetImagePixels8, int, (XImage *image, unsigned int width, 96a966c04fSmrg unsigned int height, PixelsMap *pmap)); 97a966c04fSmrg 98a966c04fSmrgLFUNC(GetImagePixels1, int, (XImage *image, unsigned int width, 99a966c04fSmrg unsigned int height, PixelsMap *pmap, 100a966c04fSmrg storeFuncPtr storeFunc)); 101a966c04fSmrg# else /* AMIGA */ 102a966c04fSmrgLFUNC(AGetImagePixels, int, (XImage *image, unsigned int width, 103a966c04fSmrg unsigned int height, PixelsMap *pmap, 104a966c04fSmrg storeFuncPtr storeFunc)); 105a966c04fSmrg# endif/* AMIGA */ 106a966c04fSmrg#else /* ndef FOR_MSW */ 107a966c04fSmrgLFUNC(MSWGetImagePixels, int, (Display *d, XImage *image, unsigned int width, 108a966c04fSmrg unsigned int height, PixelsMap *pmap, 109a966c04fSmrg storeFuncPtr storeFunc)); 110a966c04fSmrg#endif 111a966c04fSmrgLFUNC(ScanTransparentColor, int, (XpmColor *color, unsigned int cpp, 112a966c04fSmrg XpmAttributes *attributes)); 113a966c04fSmrg 11497cf2ee2SmrgLFUNC(ScanOtherColors, int, (Display *display, XpmColor *colors, 11597cf2ee2Smrg unsigned int ncolors, 116a966c04fSmrg Pixel *pixels, unsigned int mask, 117a966c04fSmrg unsigned int cpp, XpmAttributes *attributes)); 118a966c04fSmrg 119a966c04fSmrg/* 120a966c04fSmrg * This function stores the given pixel in the given arrays which are grown 121a966c04fSmrg * if not large enough. 122a966c04fSmrg */ 123a966c04fSmrgstatic int 1242e2dd055SmrgstorePixel( 1252e2dd055Smrg Pixel pixel, 1262e2dd055Smrg PixelsMap *pmap, 1272e2dd055Smrg unsigned int *index_return) 128a966c04fSmrg{ 129a966c04fSmrg unsigned int i; 130a966c04fSmrg Pixel *p; 131a966c04fSmrg unsigned int ncolors; 132a966c04fSmrg 133a966c04fSmrg if (*index_return) { /* this is a transparent pixel! */ 134a966c04fSmrg *index_return = 0; 135a966c04fSmrg return 0; 136a966c04fSmrg } 137a966c04fSmrg ncolors = pmap->ncolors; 138a966c04fSmrg p = pmap->pixels + pmap->mask_pixel; 139a966c04fSmrg for (i = pmap->mask_pixel; i < ncolors; i++, p++) 140a966c04fSmrg if (*p == pixel) 141a966c04fSmrg break; 142a966c04fSmrg if (i == ncolors) { 143a966c04fSmrg if (ncolors >= pmap->size) { 144a966c04fSmrg pmap->size *= 2; 145a966c04fSmrg p = (Pixel *) XpmRealloc(pmap->pixels, sizeof(Pixel) * pmap->size); 146a966c04fSmrg if (!p) 147a966c04fSmrg return (1); 148a966c04fSmrg pmap->pixels = p; 149a966c04fSmrg 150a966c04fSmrg } 151a966c04fSmrg (pmap->pixels)[ncolors] = pixel; 152a966c04fSmrg pmap->ncolors++; 153a966c04fSmrg } 154a966c04fSmrg *index_return = i; 155a966c04fSmrg return 0; 156a966c04fSmrg} 157a966c04fSmrg 158a966c04fSmrgstatic int 1592e2dd055SmrgstoreMaskPixel( 1602e2dd055Smrg Pixel pixel, 1612e2dd055Smrg PixelsMap *pmap, 1622e2dd055Smrg unsigned int *index_return) 163a966c04fSmrg{ 164a966c04fSmrg if (!pixel) { 165a966c04fSmrg if (!pmap->ncolors) { 166a966c04fSmrg pmap->ncolors = 1; 167a966c04fSmrg (pmap->pixels)[0] = 0; 168a966c04fSmrg pmap->mask_pixel = 1; 169a966c04fSmrg } 170a966c04fSmrg *index_return = 1; 171a966c04fSmrg } else 172a966c04fSmrg *index_return = 0; 173a966c04fSmrg return 0; 174a966c04fSmrg} 175a966c04fSmrg 176a966c04fSmrg/* function call in case of error */ 177a966c04fSmrg#undef RETURN 178a966c04fSmrg#define RETURN(status) \ 179a966c04fSmrgdo { \ 180a966c04fSmrg ErrorStatus = status; \ 181a966c04fSmrg goto error; \ 182a966c04fSmrg} while(0) 183a966c04fSmrg 184a966c04fSmrg/* 18519569120Smrg * This function scans the given image and stores the found information in 186a966c04fSmrg * the given XpmImage structure. 187a966c04fSmrg */ 188a966c04fSmrgint 1892e2dd055SmrgXpmCreateXpmImageFromImage( 1902e2dd055Smrg Display *display, 1912e2dd055Smrg XImage *image, 1922e2dd055Smrg XImage *shapeimage, 1932e2dd055Smrg XpmImage *xpmimage, 1942e2dd055Smrg XpmAttributes *attributes) 195a966c04fSmrg{ 196a966c04fSmrg /* variables stored in the XpmAttributes structure */ 197a966c04fSmrg unsigned int cpp; 198a966c04fSmrg 199a966c04fSmrg /* variables to return */ 200a966c04fSmrg PixelsMap pmap; 201a966c04fSmrg XpmColor *colorTable = NULL; 202a966c04fSmrg int ErrorStatus = 0; 203a966c04fSmrg 204a966c04fSmrg /* calculation variables */ 205a966c04fSmrg unsigned int width = 0; 206a966c04fSmrg unsigned int height = 0; 207a966c04fSmrg unsigned int cppm; /* minimum chars per pixel */ 208a966c04fSmrg unsigned int c; 209a966c04fSmrg 210a966c04fSmrg /* initialize pmap */ 211a966c04fSmrg pmap.pixels = NULL; 212a966c04fSmrg pmap.pixelindex = NULL; 213a966c04fSmrg pmap.size = 256; /* should be enough most of the time */ 214a966c04fSmrg pmap.ncolors = 0; 215a966c04fSmrg pmap.mask_pixel = 0; 216a966c04fSmrg 217a966c04fSmrg /* 218a966c04fSmrg * get geometry 219a966c04fSmrg */ 220a966c04fSmrg if (image) { 221a966c04fSmrg width = image->width; 222a966c04fSmrg height = image->height; 223a966c04fSmrg } else if (shapeimage) { 224a966c04fSmrg width = shapeimage->width; 225a966c04fSmrg height = shapeimage->height; 226a966c04fSmrg } 227a966c04fSmrg 228a966c04fSmrg /* 229a966c04fSmrg * retrieve information from the XpmAttributes 230a966c04fSmrg */ 231a966c04fSmrg if (attributes && (attributes->valuemask & XpmCharsPerPixel 232a966c04fSmrg/* 3.2 backward compatibility code */ 233a966c04fSmrg || attributes->valuemask & XpmInfos)) 234a966c04fSmrg/* end 3.2 bc */ 235a966c04fSmrg cpp = attributes->cpp; 236a966c04fSmrg else 237a966c04fSmrg cpp = 0; 238a966c04fSmrg 239a966c04fSmrg if ((height > 0 && width >= UINT_MAX / height) || 240a966c04fSmrg width * height >= UINT_MAX / sizeof(unsigned int)) 241a966c04fSmrg RETURN(XpmNoMemory); 242a966c04fSmrg pmap.pixelindex = 243a966c04fSmrg (unsigned int *) XpmCalloc(width * height, sizeof(unsigned int)); 244a966c04fSmrg if (!pmap.pixelindex) 245a966c04fSmrg RETURN(XpmNoMemory); 246a966c04fSmrg 24797cf2ee2Smrg if (pmap.size >= UINT_MAX / sizeof(Pixel)) 248a966c04fSmrg RETURN(XpmNoMemory); 249a966c04fSmrg 250a966c04fSmrg pmap.pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * pmap.size); 251a966c04fSmrg if (!pmap.pixels) 252a966c04fSmrg RETURN(XpmNoMemory); 253a966c04fSmrg 254a966c04fSmrg /* 255a966c04fSmrg * scan shape mask if any 256a966c04fSmrg */ 257a966c04fSmrg if (shapeimage) { 258a966c04fSmrg#ifndef FOR_MSW 259a966c04fSmrg# ifndef AMIGA 260a966c04fSmrg ErrorStatus = GetImagePixels1(shapeimage, width, height, &pmap, 261a966c04fSmrg storeMaskPixel); 262a966c04fSmrg# else 263a966c04fSmrg ErrorStatus = AGetImagePixels(shapeimage, width, height, &pmap, 264a966c04fSmrg storeMaskPixel); 265a966c04fSmrg# endif 266a966c04fSmrg#else 267a966c04fSmrg ErrorStatus = MSWGetImagePixels(display, shapeimage, width, height, 268a966c04fSmrg &pmap, storeMaskPixel); 269a966c04fSmrg#endif 270a966c04fSmrg if (ErrorStatus != XpmSuccess) 271a966c04fSmrg RETURN(ErrorStatus); 272a966c04fSmrg } 273a966c04fSmrg 274a966c04fSmrg /* 275a966c04fSmrg * scan the image data 27697cf2ee2Smrg * 277a966c04fSmrg * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use optimized 278a966c04fSmrg * functions, otherwise use slower but sure general one. 27997cf2ee2Smrg * 280a966c04fSmrg */ 281a966c04fSmrg 282a966c04fSmrg if (image) { 283a966c04fSmrg#ifndef FOR_MSW 284a966c04fSmrg# ifndef AMIGA 285a966c04fSmrg if (((image->bits_per_pixel | image->depth) == 1) && 286a966c04fSmrg (image->byte_order == image->bitmap_bit_order)) 287a966c04fSmrg ErrorStatus = GetImagePixels1(image, width, height, &pmap, 288a966c04fSmrg storePixel); 289a966c04fSmrg else if (image->format == ZPixmap) { 290a966c04fSmrg if (image->bits_per_pixel == 8) 291a966c04fSmrg ErrorStatus = GetImagePixels8(image, width, height, &pmap); 292a966c04fSmrg else if (image->bits_per_pixel == 16) 293a966c04fSmrg ErrorStatus = GetImagePixels16(image, width, height, &pmap); 294a966c04fSmrg else if (image->bits_per_pixel == 32) 295a966c04fSmrg ErrorStatus = GetImagePixels32(image, width, height, &pmap); 296a966c04fSmrg } else 297a966c04fSmrg ErrorStatus = GetImagePixels(image, width, height, &pmap); 298a966c04fSmrg# else 299a966c04fSmrg ErrorStatus = AGetImagePixels(image, width, height, &pmap, 300a966c04fSmrg storePixel); 301a966c04fSmrg# endif 302a966c04fSmrg#else 303a966c04fSmrg ErrorStatus = MSWGetImagePixels(display, image, width, height, &pmap, 304a966c04fSmrg storePixel); 305a966c04fSmrg#endif 306a966c04fSmrg if (ErrorStatus != XpmSuccess) 307a966c04fSmrg RETURN(ErrorStatus); 308a966c04fSmrg } 309a966c04fSmrg 310a966c04fSmrg /* 311a966c04fSmrg * get rgb values and a string of char, and possibly a name for each 312a966c04fSmrg * color 313a966c04fSmrg */ 314a966c04fSmrg if (pmap.ncolors >= UINT_MAX / sizeof(XpmColor)) 315a966c04fSmrg RETURN(XpmNoMemory); 316a966c04fSmrg colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor)); 317a966c04fSmrg if (!colorTable) 318a966c04fSmrg RETURN(XpmNoMemory); 319a966c04fSmrg 320a966c04fSmrg /* compute the minimal cpp */ 321a966c04fSmrg for (cppm = 1, c = MAXPRINTABLE; pmap.ncolors > c; cppm++) 322a966c04fSmrg c *= MAXPRINTABLE; 323a966c04fSmrg if (cpp < cppm) 324a966c04fSmrg cpp = cppm; 325a966c04fSmrg 326a966c04fSmrg if (pmap.mask_pixel) { 327a966c04fSmrg ErrorStatus = ScanTransparentColor(colorTable, cpp, attributes); 328a966c04fSmrg if (ErrorStatus != XpmSuccess) 329a966c04fSmrg RETURN(ErrorStatus); 330a966c04fSmrg } 331a966c04fSmrg 332a966c04fSmrg ErrorStatus = ScanOtherColors(display, colorTable, pmap.ncolors, 333a966c04fSmrg pmap.pixels, pmap.mask_pixel, cpp, 334a966c04fSmrg attributes); 335a966c04fSmrg if (ErrorStatus != XpmSuccess) 336a966c04fSmrg RETURN(ErrorStatus); 337a966c04fSmrg 338a966c04fSmrg /* 33919569120Smrg * store found information in the XpmImage structure 340a966c04fSmrg */ 341a966c04fSmrg xpmimage->width = width; 342a966c04fSmrg xpmimage->height = height; 343a966c04fSmrg xpmimage->cpp = cpp; 344a966c04fSmrg xpmimage->ncolors = pmap.ncolors; 345a966c04fSmrg xpmimage->colorTable = colorTable; 346a966c04fSmrg xpmimage->data = pmap.pixelindex; 347a966c04fSmrg 348a966c04fSmrg XpmFree(pmap.pixels); 349a966c04fSmrg return (XpmSuccess); 350a966c04fSmrg 351a966c04fSmrg/* exit point in case of error, free only locally allocated variables */ 352a966c04fSmrgerror: 353a966c04fSmrg if (pmap.pixelindex) 354a966c04fSmrg XpmFree(pmap.pixelindex); 355a966c04fSmrg if (pmap.pixels) 356a966c04fSmrg XpmFree(pmap.pixels); 357a966c04fSmrg if (colorTable) 358a966c04fSmrg xpmFreeColorTable(colorTable, pmap.ncolors); 359a966c04fSmrg 360a966c04fSmrg return (ErrorStatus); 361a966c04fSmrg} 362a966c04fSmrg 363a966c04fSmrgstatic int 3642e2dd055SmrgScanTransparentColor( 3652e2dd055Smrg XpmColor *color, 3662e2dd055Smrg unsigned int cpp, 3672e2dd055Smrg XpmAttributes *attributes) 368a966c04fSmrg{ 369a966c04fSmrg char *s; 370a966c04fSmrg unsigned int a, b, c; 371a966c04fSmrg 372a966c04fSmrg /* first get a character string */ 373a966c04fSmrg a = 0; 374a966c04fSmrg if (cpp >= UINT_MAX - 1) 375a966c04fSmrg return (XpmNoMemory); 376a966c04fSmrg if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) 377a966c04fSmrg return (XpmNoMemory); 378a966c04fSmrg *s++ = printable[c = a % MAXPRINTABLE]; 379a966c04fSmrg for (b = 1; b < cpp; b++, s++) 380a966c04fSmrg *s = printable[c = ((a - c) / MAXPRINTABLE) % MAXPRINTABLE]; 381a966c04fSmrg *s = '\0'; 382a966c04fSmrg 38319569120Smrg /* then retrieve related info from the attributes if any */ 384a966c04fSmrg if (attributes && (attributes->valuemask & XpmColorTable 385a966c04fSmrg/* 3.2 backward compatibility code */ 386a966c04fSmrg || attributes->valuemask & XpmInfos) 387a966c04fSmrg/* end 3.2 bc */ 388a966c04fSmrg && attributes->mask_pixel != XpmUndefPixel) { 389a966c04fSmrg 390a966c04fSmrg unsigned int key; 391a966c04fSmrg char **defaults = (char **) color; 392a966c04fSmrg char **mask_defaults; 393a966c04fSmrg 394a966c04fSmrg/* 3.2 backward compatibility code */ 395a966c04fSmrg if (attributes->valuemask & XpmColorTable) 396a966c04fSmrg/* end 3.2 bc */ 397a966c04fSmrg mask_defaults = (char **) ( 398a966c04fSmrg attributes->colorTable + attributes->mask_pixel); 399a966c04fSmrg/* 3.2 backward compatibility code */ 400a966c04fSmrg else 401a966c04fSmrg mask_defaults = (char **) 402a966c04fSmrg ((XpmColor **) attributes->colorTable)[attributes->mask_pixel]; 403a966c04fSmrg/* end 3.2 bc */ 404a966c04fSmrg for (key = 1; key <= NKEYS; key++) { 405a966c04fSmrg if ((s = mask_defaults[key])) { 406a966c04fSmrg defaults[key] = (char *) xpmstrdup(s); 407a966c04fSmrg if (!defaults[key]) 408a966c04fSmrg return (XpmNoMemory); 409a966c04fSmrg } 410a966c04fSmrg } 411a966c04fSmrg } else { 412a966c04fSmrg color->c_color = (char *) xpmstrdup(TRANSPARENT_COLOR); 413a966c04fSmrg if (!color->c_color) 414a966c04fSmrg return (XpmNoMemory); 415a966c04fSmrg } 416a966c04fSmrg return (XpmSuccess); 417a966c04fSmrg} 418a966c04fSmrg 419a966c04fSmrgstatic int 4202e2dd055SmrgScanOtherColors( 4212e2dd055Smrg Display *display, 4222e2dd055Smrg XpmColor *colors, 4232e2dd055Smrg unsigned int ncolors, 4242e2dd055Smrg Pixel *pixels, 4252e2dd055Smrg unsigned int mask, 4262e2dd055Smrg unsigned int cpp, 4272e2dd055Smrg XpmAttributes *attributes) 428a966c04fSmrg{ 429a966c04fSmrg /* variables stored in the XpmAttributes structure */ 430a966c04fSmrg Colormap colormap; 431a966c04fSmrg char *rgb_fname; 432a966c04fSmrg 433a966c04fSmrg#ifndef FOR_MSW 434a966c04fSmrg xpmRgbName rgbn[MAX_RGBNAMES]; 435a966c04fSmrg#else 43697cf2ee2Smrg xpmRgbName *rgbn = NULL; 43797cf2ee2Smrg#endif 438a966c04fSmrg int rgbn_max = 0; 439a966c04fSmrg unsigned int i, j, c, i2; 440a966c04fSmrg XpmColor *color; 441a966c04fSmrg XColor *xcolors = NULL, *xcolor; 442a966c04fSmrg char *colorname, *s; 443a966c04fSmrg XpmColor *colorTable = NULL, **oldColorTable = NULL; 444a966c04fSmrg unsigned int ancolors = 0; 445a966c04fSmrg Pixel *apixels = NULL; 446a966c04fSmrg unsigned int mask_pixel = 0; 447a966c04fSmrg Bool found; 448a966c04fSmrg 449a966c04fSmrg /* retrieve information from the XpmAttributes */ 450a966c04fSmrg if (attributes && (attributes->valuemask & XpmColormap)) 451a966c04fSmrg colormap = attributes->colormap; 452a966c04fSmrg else 453a966c04fSmrg colormap = XDefaultColormap(display, XDefaultScreen(display)); 454a966c04fSmrg if (attributes && (attributes->valuemask & XpmRgbFilename)) 455a966c04fSmrg rgb_fname = attributes->rgb_fname; 456a966c04fSmrg else 457a966c04fSmrg rgb_fname = NULL; 458a966c04fSmrg 459a966c04fSmrg /* start from the right element */ 460a966c04fSmrg if (mask) { 461a966c04fSmrg colors++; 462a966c04fSmrg ncolors--; 463a966c04fSmrg pixels++; 464a966c04fSmrg } 465a966c04fSmrg 466a966c04fSmrg /* first get character strings and rgb values */ 467a966c04fSmrg if (ncolors >= UINT_MAX / sizeof(XColor) || cpp >= UINT_MAX - 1) 468a966c04fSmrg return (XpmNoMemory); 469a966c04fSmrg xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors); 470a966c04fSmrg if (!xcolors) 471a966c04fSmrg return (XpmNoMemory); 472a966c04fSmrg 473a966c04fSmrg for (i = 0, i2 = mask, color = colors, xcolor = xcolors; 474a966c04fSmrg i < ncolors; i++, i2++, color++, xcolor++, pixels++) { 475a966c04fSmrg 476a966c04fSmrg if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) { 477a966c04fSmrg XpmFree(xcolors); 478a966c04fSmrg return (XpmNoMemory); 479a966c04fSmrg } 480a966c04fSmrg *s++ = printable[c = i2 % MAXPRINTABLE]; 481a966c04fSmrg for (j = 1; j < cpp; j++, s++) 482a966c04fSmrg *s = printable[c = ((i2 - c) / MAXPRINTABLE) % MAXPRINTABLE]; 483a966c04fSmrg *s = '\0'; 484a966c04fSmrg 485a966c04fSmrg xcolor->pixel = *pixels; 486a966c04fSmrg } 487a966c04fSmrg XQueryColors(display, colormap, xcolors, ncolors); 488a966c04fSmrg 489a966c04fSmrg#ifndef FOR_MSW 490a966c04fSmrg /* read the rgb file if any was specified */ 491a966c04fSmrg if (rgb_fname) 492a966c04fSmrg rgbn_max = xpmReadRgbNames(attributes->rgb_fname, rgbn); 493a966c04fSmrg#else 494a966c04fSmrg /* FOR_MSW: rgb names and values are hardcoded in rgbtab.h */ 495a966c04fSmrg rgbn_max = xpmReadRgbNames(NULL, NULL); 496a966c04fSmrg#endif 497a966c04fSmrg 498a966c04fSmrg if (attributes && attributes->valuemask & XpmColorTable) { 499a966c04fSmrg colorTable = attributes->colorTable; 500a966c04fSmrg ancolors = attributes->ncolors; 501a966c04fSmrg apixels = attributes->pixels; 502a966c04fSmrg mask_pixel = attributes->mask_pixel; 503a966c04fSmrg } 504a966c04fSmrg/* 3.2 backward compatibility code */ 505a966c04fSmrg else if (attributes && attributes->valuemask & XpmInfos) { 506a966c04fSmrg oldColorTable = (XpmColor **) attributes->colorTable; 507a966c04fSmrg ancolors = attributes->ncolors; 508a966c04fSmrg apixels = attributes->pixels; 509a966c04fSmrg mask_pixel = attributes->mask_pixel; 510a966c04fSmrg } 511a966c04fSmrg/* end 3.2 bc */ 512a966c04fSmrg 513a966c04fSmrg for (i = 0, color = colors, xcolor = xcolors; i < ncolors; 514a966c04fSmrg i++, color++, xcolor++) { 515a966c04fSmrg 516a966c04fSmrg /* look for related info from the attributes if any */ 517a966c04fSmrg found = False; 518a966c04fSmrg if (ancolors) { 519a966c04fSmrg unsigned int offset = 0; 520a966c04fSmrg 521a966c04fSmrg for (j = 0; j < ancolors; j++) { 522a966c04fSmrg if (j == mask_pixel) { 523a966c04fSmrg offset = 1; 524a966c04fSmrg continue; 525a966c04fSmrg } 526a966c04fSmrg if (apixels[j - offset] == xcolor->pixel) 527a966c04fSmrg break; 528a966c04fSmrg } 529a966c04fSmrg if (j != ancolors) { 530a966c04fSmrg unsigned int key; 531a966c04fSmrg char **defaults = (char **) color; 532a966c04fSmrg char **adefaults; 533a966c04fSmrg 534a966c04fSmrg/* 3.2 backward compatibility code */ 535a966c04fSmrg if (oldColorTable) 536a966c04fSmrg adefaults = (char **) oldColorTable[j]; 537a966c04fSmrg else 538a966c04fSmrg/* end 3.2 bc */ 539a966c04fSmrg adefaults = (char **) (colorTable + j); 540a966c04fSmrg 541a966c04fSmrg found = True; 542a966c04fSmrg for (key = 1; key <= NKEYS; key++) { 543a966c04fSmrg if ((s = adefaults[key])) 544a966c04fSmrg defaults[key] = (char *) xpmstrdup(s); 545a966c04fSmrg } 546a966c04fSmrg } 547a966c04fSmrg } 548a966c04fSmrg if (!found) { 549a966c04fSmrg /* if nothing found look for a color name */ 550a966c04fSmrg colorname = NULL; 551a966c04fSmrg if (rgbn_max) 552a966c04fSmrg colorname = xpmGetRgbName(rgbn, rgbn_max, xcolor->red, 553a966c04fSmrg xcolor->green, xcolor->blue); 554a966c04fSmrg if (colorname) 555a966c04fSmrg color->c_color = (char *) xpmstrdup(colorname); 556a966c04fSmrg else { 557a966c04fSmrg /* at last store the rgb value */ 558a966c04fSmrg char buf[BUFSIZ]; 559a966c04fSmrg#ifndef FOR_MSW 560a966c04fSmrg sprintf(buf, "#%04X%04X%04X", 561a966c04fSmrg xcolor->red, xcolor->green, xcolor->blue); 56297cf2ee2Smrg#else 563a966c04fSmrg sprintf(buf, "#%02x%02x%02x", 564a966c04fSmrg xcolor->red, xcolor->green, xcolor->blue); 56597cf2ee2Smrg#endif 566a966c04fSmrg color->c_color = (char *) xpmstrdup(buf); 567a966c04fSmrg } 568a966c04fSmrg if (!color->c_color) { 569a966c04fSmrg XpmFree(xcolors); 570a966c04fSmrg xpmFreeRgbNames(rgbn, rgbn_max); 571a966c04fSmrg return (XpmNoMemory); 572a966c04fSmrg } 573a966c04fSmrg } 574a966c04fSmrg } 575a966c04fSmrg 576a966c04fSmrg XpmFree(xcolors); 577a966c04fSmrg xpmFreeRgbNames(rgbn, rgbn_max); 578a966c04fSmrg return (XpmSuccess); 579a966c04fSmrg} 580a966c04fSmrg 581a966c04fSmrg#ifndef FOR_MSW 582a966c04fSmrg# ifndef AMIGA 583a966c04fSmrg/* 584a966c04fSmrg * The functions below are written from X11R5 MIT's code (XImUtil.c) 585a966c04fSmrg * 586a966c04fSmrg * The idea is to have faster functions than the standard XGetPixel function 587a966c04fSmrg * to scan the image data. Indeed we can speed up things by suppressing tests 588a966c04fSmrg * performed for each pixel. We do exactly the same tests but at the image 589a966c04fSmrg * level. 590a966c04fSmrg */ 591a966c04fSmrg 59297cf2ee2Smrgstatic unsigned long const low_bits_table[] = { 593a966c04fSmrg 0x00000000, 0x00000001, 0x00000003, 0x00000007, 594a966c04fSmrg 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 595a966c04fSmrg 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 596a966c04fSmrg 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 597a966c04fSmrg 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 598a966c04fSmrg 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 599a966c04fSmrg 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 600a966c04fSmrg 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 601a966c04fSmrg 0xffffffff 602a966c04fSmrg}; 603a966c04fSmrg 604a966c04fSmrg/* 605a966c04fSmrg * Default method to scan pixels of an image data structure. 606a966c04fSmrg * The algorithm used is: 607a966c04fSmrg * 608a966c04fSmrg * copy the source bitmap_unit or Zpixel into temp 609a966c04fSmrg * normalize temp if needed 610a966c04fSmrg * extract the pixel bits into return value 611a966c04fSmrg * 612a966c04fSmrg */ 613a966c04fSmrg 614a966c04fSmrgstatic int 6152e2dd055SmrgGetImagePixels( 6162e2dd055Smrg XImage *image, 6172e2dd055Smrg unsigned int width, 6182e2dd055Smrg unsigned int height, 6192e2dd055Smrg PixelsMap *pmap) 620a966c04fSmrg{ 621a966c04fSmrg char *src; 622a966c04fSmrg char *dst; 623a966c04fSmrg unsigned int *iptr; 624a966c04fSmrg char *data; 625a966c04fSmrg unsigned int x, y; 626a966c04fSmrg int bits, depth, ibu, ibpp, offset, i; 627a966c04fSmrg unsigned long lbt; 628a966c04fSmrg Pixel pixel, px; 629a966c04fSmrg 630a966c04fSmrg data = image->data; 631a966c04fSmrg iptr = pmap->pixelindex; 632a966c04fSmrg depth = image->depth; 633a966c04fSmrg lbt = low_bits_table[depth]; 634a966c04fSmrg ibpp = image->bits_per_pixel; 635a966c04fSmrg offset = image->xoffset; 636a966c04fSmrg 637a966c04fSmrg if (image->bitmap_unit < 0) 638a966c04fSmrg return (XpmNoMemory); 639a966c04fSmrg 640a966c04fSmrg if ((image->bits_per_pixel | image->depth) == 1) { 641a966c04fSmrg ibu = image->bitmap_unit; 642a966c04fSmrg for (y = 0; y < height; y++) 643a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 644a966c04fSmrg src = &data[XYINDEX(x, y, image)]; 645a966c04fSmrg dst = (char *) &pixel; 646a966c04fSmrg pixel = 0; 647a966c04fSmrg for (i = ibu >> 3; --i >= 0;) 648a966c04fSmrg *dst++ = *src++; 649a966c04fSmrg XYNORMALIZE(&pixel, image); 650a966c04fSmrg bits = (x + offset) % ibu; 651a966c04fSmrg pixel = ((((char *) &pixel)[bits >> 3]) >> (bits & 7)) & 1; 652a966c04fSmrg if (ibpp != depth) 653a966c04fSmrg pixel &= lbt; 654a966c04fSmrg if (storePixel(pixel, pmap, iptr)) 655a966c04fSmrg return (XpmNoMemory); 656a966c04fSmrg } 657a966c04fSmrg } else if (image->format == XYPixmap) { 658a966c04fSmrg int nbytes, bpl, j; 659a966c04fSmrg long plane = 0; 660a966c04fSmrg ibu = image->bitmap_unit; 661a966c04fSmrg nbytes = ibu >> 3; 662a966c04fSmrg bpl = image->bytes_per_line; 663a966c04fSmrg for (y = 0; y < height; y++) 664a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 665a966c04fSmrg pixel = 0; 666a966c04fSmrg plane = 0; 667a966c04fSmrg for (i = depth; --i >= 0;) { 668a966c04fSmrg src = &data[XYINDEX(x, y, image) + plane]; 669a966c04fSmrg dst = (char *) &px; 670a966c04fSmrg px = 0; 671a966c04fSmrg for (j = nbytes; --j >= 0;) 672a966c04fSmrg *dst++ = *src++; 673a966c04fSmrg XYNORMALIZE(&px, image); 674a966c04fSmrg bits = (x + offset) % ibu; 675a966c04fSmrg pixel = (pixel << 1) | 676a966c04fSmrg (((((char *) &px)[bits >> 3]) >> (bits & 7)) & 1); 677a966c04fSmrg plane = plane + (bpl * height); 678a966c04fSmrg } 679a966c04fSmrg if (ibpp != depth) 680a966c04fSmrg pixel &= lbt; 681a966c04fSmrg if (storePixel(pixel, pmap, iptr)) 682a966c04fSmrg return (XpmNoMemory); 683a966c04fSmrg } 684a966c04fSmrg } else if (image->format == ZPixmap) { 685a966c04fSmrg for (y = 0; y < height; y++) 686a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 687a966c04fSmrg src = &data[ZINDEX(x, y, image)]; 688a966c04fSmrg dst = (char *) &px; 689a966c04fSmrg px = 0; 690a966c04fSmrg for (i = (ibpp + 7) >> 3; --i >= 0;) 691a966c04fSmrg *dst++ = *src++; 692a966c04fSmrg ZNORMALIZE(&px, image); 693a966c04fSmrg pixel = 0; 694a966c04fSmrg for (i = sizeof(unsigned long); --i >= 0;) 695a966c04fSmrg pixel = (pixel << 8) | ((unsigned char *) &px)[i]; 696a966c04fSmrg if (ibpp == 4) { 697a966c04fSmrg if (x & 1) 698a966c04fSmrg pixel >>= 4; 699a966c04fSmrg else 700a966c04fSmrg pixel &= 0xf; 701a966c04fSmrg } 702a966c04fSmrg if (ibpp != depth) 703a966c04fSmrg pixel &= lbt; 704a966c04fSmrg if (storePixel(pixel, pmap, iptr)) 705a966c04fSmrg return (XpmNoMemory); 706a966c04fSmrg } 707a966c04fSmrg } else 708a966c04fSmrg return (XpmColorError); /* actually a bad image */ 709a966c04fSmrg return (XpmSuccess); 710a966c04fSmrg} 711a966c04fSmrg 712a966c04fSmrg/* 713a966c04fSmrg * scan pixels of a 32-bits Z image data structure 714a966c04fSmrg */ 715a966c04fSmrg 716a966c04fSmrg#if !defined(WORD64) && !defined(LONG64) 717a966c04fSmrgstatic unsigned long byteorderpixel = MSBFirst << 24; 718a966c04fSmrg#endif 719a966c04fSmrg 720a966c04fSmrgstatic int 7212e2dd055SmrgGetImagePixels32( 7222e2dd055Smrg XImage *image, 7232e2dd055Smrg unsigned int width, 7242e2dd055Smrg unsigned int height, 7252e2dd055Smrg PixelsMap *pmap) 726a966c04fSmrg{ 727a966c04fSmrg unsigned char *addr; 728a966c04fSmrg unsigned char *data; 729a966c04fSmrg unsigned int *iptr; 730a966c04fSmrg unsigned int x, y; 731a966c04fSmrg unsigned long lbt; 732a966c04fSmrg Pixel pixel; 733a966c04fSmrg int depth; 734a966c04fSmrg 735a966c04fSmrg data = (unsigned char *) image->data; 736a966c04fSmrg iptr = pmap->pixelindex; 737a966c04fSmrg depth = image->depth; 738a966c04fSmrg lbt = low_bits_table[depth]; 739a966c04fSmrg#if !defined(WORD64) && !defined(LONG64) 740a966c04fSmrg if (*((char *) &byteorderpixel) == image->byte_order) { 741a966c04fSmrg for (y = 0; y < height; y++) 742a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 743a966c04fSmrg addr = &data[ZINDEX32(x, y, image)]; 744a966c04fSmrg pixel = *((unsigned long *) addr); 745a966c04fSmrg if (depth != 32) 746a966c04fSmrg pixel &= lbt; 747a966c04fSmrg if (storePixel(pixel, pmap, iptr)) 748a966c04fSmrg return (XpmNoMemory); 749a966c04fSmrg } 750a966c04fSmrg } else 751a966c04fSmrg#endif 752a966c04fSmrg if (image->byte_order == MSBFirst) 753a966c04fSmrg for (y = 0; y < height; y++) 754a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 755a966c04fSmrg addr = &data[ZINDEX32(x, y, image)]; 756a966c04fSmrg pixel = ((unsigned long) addr[0] << 24 | 757a966c04fSmrg (unsigned long) addr[1] << 16 | 758a966c04fSmrg (unsigned long) addr[2] << 8 | 759a966c04fSmrg addr[3]); 760a966c04fSmrg if (depth != 32) 761a966c04fSmrg pixel &= lbt; 762a966c04fSmrg if (storePixel(pixel, pmap, iptr)) 763a966c04fSmrg return (XpmNoMemory); 764a966c04fSmrg } 765a966c04fSmrg else 766a966c04fSmrg for (y = 0; y < height; y++) 767a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 768a966c04fSmrg addr = &data[ZINDEX32(x, y, image)]; 769a966c04fSmrg pixel = (addr[0] | 770a966c04fSmrg (unsigned long) addr[1] << 8 | 771a966c04fSmrg (unsigned long) addr[2] << 16 | 772a966c04fSmrg (unsigned long) addr[3] << 24); 773a966c04fSmrg if (depth != 32) 774a966c04fSmrg pixel &= lbt; 775a966c04fSmrg if (storePixel(pixel, pmap, iptr)) 776a966c04fSmrg return (XpmNoMemory); 777a966c04fSmrg } 778a966c04fSmrg return (XpmSuccess); 779a966c04fSmrg} 780a966c04fSmrg 781a966c04fSmrg/* 782a966c04fSmrg * scan pixels of a 16-bits Z image data structure 783a966c04fSmrg */ 784a966c04fSmrg 785a966c04fSmrgstatic int 7862e2dd055SmrgGetImagePixels16( 7872e2dd055Smrg XImage *image, 7882e2dd055Smrg unsigned int width, 7892e2dd055Smrg unsigned int height, 7902e2dd055Smrg PixelsMap *pmap) 791a966c04fSmrg{ 792a966c04fSmrg unsigned char *addr; 793a966c04fSmrg unsigned char *data; 794a966c04fSmrg unsigned int *iptr; 795a966c04fSmrg unsigned int x, y; 796a966c04fSmrg unsigned long lbt; 797a966c04fSmrg Pixel pixel; 798a966c04fSmrg int depth; 799a966c04fSmrg 800a966c04fSmrg data = (unsigned char *) image->data; 801a966c04fSmrg iptr = pmap->pixelindex; 802a966c04fSmrg depth = image->depth; 803a966c04fSmrg lbt = low_bits_table[depth]; 804a966c04fSmrg if (image->byte_order == MSBFirst) 805a966c04fSmrg for (y = 0; y < height; y++) 806a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 807a966c04fSmrg addr = &data[ZINDEX16(x, y, image)]; 808a966c04fSmrg pixel = addr[0] << 8 | addr[1]; 809a966c04fSmrg if (depth != 16) 810a966c04fSmrg pixel &= lbt; 811a966c04fSmrg if (storePixel(pixel, pmap, iptr)) 812a966c04fSmrg return (XpmNoMemory); 813a966c04fSmrg } 814a966c04fSmrg else 815a966c04fSmrg for (y = 0; y < height; y++) 816a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 817a966c04fSmrg addr = &data[ZINDEX16(x, y, image)]; 818a966c04fSmrg pixel = addr[0] | addr[1] << 8; 819a966c04fSmrg if (depth != 16) 820a966c04fSmrg pixel &= lbt; 821a966c04fSmrg if (storePixel(pixel, pmap, iptr)) 822a966c04fSmrg return (XpmNoMemory); 823a966c04fSmrg } 824a966c04fSmrg return (XpmSuccess); 825a966c04fSmrg} 826a966c04fSmrg 827a966c04fSmrg/* 828a966c04fSmrg * scan pixels of a 8-bits Z image data structure 829a966c04fSmrg */ 830a966c04fSmrg 831a966c04fSmrgstatic int 8322e2dd055SmrgGetImagePixels8( 8332e2dd055Smrg XImage *image, 8342e2dd055Smrg unsigned int width, 8352e2dd055Smrg unsigned int height, 8362e2dd055Smrg PixelsMap *pmap) 837a966c04fSmrg{ 838a966c04fSmrg unsigned int *iptr; 839a966c04fSmrg unsigned char *data; 840a966c04fSmrg unsigned int x, y; 841a966c04fSmrg unsigned long lbt; 842a966c04fSmrg Pixel pixel; 843a966c04fSmrg int depth; 844a966c04fSmrg 845a966c04fSmrg data = (unsigned char *) image->data; 846a966c04fSmrg iptr = pmap->pixelindex; 847a966c04fSmrg depth = image->depth; 848a966c04fSmrg lbt = low_bits_table[depth]; 849a966c04fSmrg for (y = 0; y < height; y++) 850a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 851a966c04fSmrg pixel = data[ZINDEX8(x, y, image)]; 852a966c04fSmrg if (depth != 8) 853a966c04fSmrg pixel &= lbt; 854a966c04fSmrg if (storePixel(pixel, pmap, iptr)) 855a966c04fSmrg return (XpmNoMemory); 856a966c04fSmrg } 857a966c04fSmrg return (XpmSuccess); 858a966c04fSmrg} 859a966c04fSmrg 860a966c04fSmrg/* 861a966c04fSmrg * scan pixels of a 1-bit depth Z image data structure 862a966c04fSmrg */ 863a966c04fSmrg 864a966c04fSmrgstatic int 8652e2dd055SmrgGetImagePixels1( 8662e2dd055Smrg XImage *image, 8672e2dd055Smrg unsigned int width, 8682e2dd055Smrg unsigned int height, 8692e2dd055Smrg PixelsMap *pmap, 8702e2dd055Smrg storeFuncPtr storeFunc) 871a966c04fSmrg{ 872a966c04fSmrg unsigned int *iptr; 873a966c04fSmrg unsigned int x, y; 874a966c04fSmrg char *data; 875a966c04fSmrg Pixel pixel; 876a966c04fSmrg int xoff, yoff, offset, bpl; 877a966c04fSmrg 878a966c04fSmrg data = image->data; 879a966c04fSmrg iptr = pmap->pixelindex; 880a966c04fSmrg offset = image->xoffset; 881a966c04fSmrg bpl = image->bytes_per_line; 882a966c04fSmrg 883a966c04fSmrg if (image->bitmap_bit_order == MSBFirst) 884a966c04fSmrg for (y = 0; y < height; y++) 885a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 886a966c04fSmrg xoff = x + offset; 887a966c04fSmrg yoff = y * bpl + (xoff >> 3); 888a966c04fSmrg xoff &= 7; 889a966c04fSmrg pixel = (data[yoff] & (0x80 >> xoff)) ? 1 : 0; 890a966c04fSmrg if ((*storeFunc) (pixel, pmap, iptr)) 891a966c04fSmrg return (XpmNoMemory); 892a966c04fSmrg } 893a966c04fSmrg else 894a966c04fSmrg for (y = 0; y < height; y++) 895a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 896a966c04fSmrg xoff = x + offset; 897a966c04fSmrg yoff = y * bpl + (xoff >> 3); 898a966c04fSmrg xoff &= 7; 899a966c04fSmrg pixel = (data[yoff] & (1 << xoff)) ? 1 : 0; 900a966c04fSmrg if ((*storeFunc) (pixel, pmap, iptr)) 901a966c04fSmrg return (XpmNoMemory); 902a966c04fSmrg } 903a966c04fSmrg return (XpmSuccess); 904a966c04fSmrg} 905a966c04fSmrg 906a966c04fSmrg# else /* AMIGA */ 907a966c04fSmrg 908a966c04fSmrg#define CLEAN_UP(status) \ 909a966c04fSmrgdo {\ 910a966c04fSmrg if (pixels) XpmFree (pixels);\ 911a966c04fSmrg if (tmp_img) FreeXImage (tmp_img);\ 912a966c04fSmrg return (status);\ 913a966c04fSmrg} while(0) 914a966c04fSmrg 915a966c04fSmrgstatic int 916a966c04fSmrgAGetImagePixels ( 917a966c04fSmrg XImage *image, 918a966c04fSmrg unsigned int width, 919a966c04fSmrg unsigned int height, 920a966c04fSmrg PixelsMap *pmap, 9212e2dd055Smrg int (*storeFunc) (Pixel, PixelsMap *, unsigned int *)) 922a966c04fSmrg{ 923a966c04fSmrg unsigned int *iptr; 924a966c04fSmrg unsigned int x, y; 925a966c04fSmrg unsigned char *pixels; 926a966c04fSmrg XImage *tmp_img; 92797cf2ee2Smrg 928a966c04fSmrg pixels = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*pixels)); 929a966c04fSmrg if (pixels == NULL) 930a966c04fSmrg return XpmNoMemory; 93197cf2ee2Smrg 932a966c04fSmrg tmp_img = AllocXImage ((((width+15)>>4)<<4), 1, image->rp->BitMap->Depth); 933a966c04fSmrg if (tmp_img == NULL) 934a966c04fSmrg CLEAN_UP (XpmNoMemory); 93597cf2ee2Smrg 936a966c04fSmrg iptr = pmap->pixelindex; 937a966c04fSmrg for (y = 0; y < height; ++y) 938a966c04fSmrg { 939a966c04fSmrg ReadPixelLine8 (image->rp, 0, y, width, pixels, tmp_img->rp); 940a966c04fSmrg for (x = 0; x < width; ++x, ++iptr) 941a966c04fSmrg { 942a966c04fSmrg if ((*storeFunc) (pixels[x], pmap, iptr)) 943a966c04fSmrg CLEAN_UP (XpmNoMemory); 944a966c04fSmrg } 945a966c04fSmrg } 94697cf2ee2Smrg 947a966c04fSmrg CLEAN_UP (XpmSuccess); 948a966c04fSmrg} 949a966c04fSmrg 950a966c04fSmrg#undef CLEAN_UP 951a966c04fSmrg 952a966c04fSmrg# endif/* AMIGA */ 953a966c04fSmrg#else /* ndef FOR_MSW */ 954a966c04fSmrgstatic int 9552e2dd055SmrgMSWGetImagePixels( 9562e2dd055Smrg Display *display, 9572e2dd055Smrg XImage *image, 9582e2dd055Smrg unsigned int width, 9592e2dd055Smrg unsigned int height, 9602e2dd055Smrg PixelsMap *pmap, 9612e2dd055Smrg int (*storeFunc) (Pixel, PixelsMap*, unsigned int *)) 962a966c04fSmrg{ 963a966c04fSmrg unsigned int *iptr; 964a966c04fSmrg unsigned int x, y; 965a966c04fSmrg Pixel pixel; 966a966c04fSmrg 967a966c04fSmrg iptr = pmap->pixelindex; 968a966c04fSmrg 969a966c04fSmrg SelectObject(*display, image->bitmap); 970a966c04fSmrg for (y = 0; y < height; y++) { 971a966c04fSmrg for (x = 0; x < width; x++, iptr++) { 972a966c04fSmrg pixel = GetPixel(*display, x, y); 973a966c04fSmrg if ((*storeFunc) (pixel, pmap, iptr)) 974a966c04fSmrg return (XpmNoMemory); 975a966c04fSmrg } 976a966c04fSmrg } 977a966c04fSmrg return (XpmSuccess); 978a966c04fSmrg} 979a966c04fSmrg 980a966c04fSmrg#endif 981a966c04fSmrg 982a966c04fSmrg#ifndef FOR_MSW 983a966c04fSmrg# ifndef AMIGA 984a966c04fSmrgint 9852e2dd055SmrgXpmCreateXpmImageFromPixmap( 9862e2dd055Smrg Display *display, 9872e2dd055Smrg Pixmap pixmap, 9882e2dd055Smrg Pixmap shapemask, 9892e2dd055Smrg XpmImage *xpmimage, 9902e2dd055Smrg XpmAttributes *attributes) 991a966c04fSmrg{ 992a966c04fSmrg XImage *ximage = NULL; 993a966c04fSmrg XImage *shapeimage = NULL; 994a966c04fSmrg unsigned int width = 0; 995a966c04fSmrg unsigned int height = 0; 996a966c04fSmrg int ErrorStatus; 997a966c04fSmrg 998a966c04fSmrg /* get geometry */ 999a966c04fSmrg if (attributes && attributes->valuemask & XpmSize) { 1000a966c04fSmrg width = attributes->width; 1001a966c04fSmrg height = attributes->height; 1002a966c04fSmrg } 1003a966c04fSmrg /* get the ximages */ 1004a966c04fSmrg if (pixmap) 1005a966c04fSmrg xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height); 1006a966c04fSmrg if (shapemask) 1007a966c04fSmrg xpmCreateImageFromPixmap(display, shapemask, &shapeimage, 1008a966c04fSmrg &width, &height); 1009a966c04fSmrg 1010a966c04fSmrg /* create the related XpmImage */ 1011a966c04fSmrg ErrorStatus = XpmCreateXpmImageFromImage(display, ximage, shapeimage, 1012a966c04fSmrg xpmimage, attributes); 1013a966c04fSmrg 1014a966c04fSmrg /* destroy the ximages */ 1015a966c04fSmrg if (ximage) 1016a966c04fSmrg XDestroyImage(ximage); 1017a966c04fSmrg if (shapeimage) 1018a966c04fSmrg XDestroyImage(shapeimage); 1019a966c04fSmrg 1020a966c04fSmrg return (ErrorStatus); 1021a966c04fSmrg} 1022a966c04fSmrg 1023a966c04fSmrg# endif/* not AMIGA */ 1024a966c04fSmrg#endif /* ndef FOR_MSW */ 1025