]>
git.saurik.com Git - wxWidgets.git/blob - src/mac/xpm/scan.c
   2  * Copyright (C) 1989-95 GROUPE BULL 
   4  * Permission is hereby granted, free of charge, to any person obtaining a copy 
   5  * of this software and associated documentation files (the "Software"), to 
   6  * deal in the Software without restriction, including without limitation the 
   7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 
   8  * sell copies of the Software, and to permit persons to whom the Software is 
   9  * furnished to do so, subject to the following conditions: 
  11  * The above copyright notice and this permission notice shall be included in 
  12  * all copies or substantial portions of the Software. 
  14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
  15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
  16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
  17  * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 
  18  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
  19  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
  21  * Except as contained in this notice, the name of GROUPE BULL shall not be 
  22  * used in advertising or otherwise to promote the sale, use or other dealings 
  23  * in this Software without prior written authorization from GROUPE BULL. 
  26 /*****************************************************************************\ 
  30 *  Scanning utility for XPM file format                                       * 
  32 *  Developed by Arnaud Le Hors                                                * 
  33 \*****************************************************************************/ 
  36  * The code related to FOR_MSW has been added by 
  37  * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 
  41  * The code related to AMIGA has been added by 
  42  * Lorens Younes (d93-hyo@nada.kth.se) 4/96 
  47 #define MAXPRINTABLE 92                 /* number of printable ascii chars 
  48                                          * minus \ and " for string compat 
  49                                          * and ? to avoid ANSI trigraphs. */ 
  51 static char *printable 
= 
  52 " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\ 
  53 ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; 
  56  * printable begin with a space, so in most case, due to my algorithm, when 
  57  * the number of different colors is less than MAXPRINTABLE, it will give a 
  58  * char follow by "nothing" (a space) in the readable xpm file 
  64     unsigned int *pixelindex
; 
  67     unsigned int mask_pixel
;            /* whether there is or not */ 
  70 LFUNC(storePixel
, int, (Pixel pixel
, PixelsMap 
*pmap
, 
  71                         unsigned int *index_return
)); 
  73 LFUNC(storeMaskPixel
, int, (Pixel pixel
, PixelsMap 
*pmap
, 
  74                             unsigned int *index_return
)); 
  76 LFUNC(PlatformGetImagePixels
, int, (Display 
*d
, XImage 
*image
, unsigned int width
, 
  77                                unsigned int height
, PixelsMap 
*pmap
, 
  78                                int (*storeFunc
) ())); 
  79 LFUNC(ScanTransparentColor
, int, (XpmColor 
*color
, unsigned int cpp
, 
  80                                   XpmAttributes 
*attributes
)); 
  82 LFUNC(ScanOtherColors
, int, (Display 
*display
, XpmColor 
*colors
, int ncolors
, 
  83                              Pixel 
*pixels
, unsigned int mask
, 
  84                              unsigned int cpp
, XpmAttributes 
*attributes
)); 
  87  * This function stores the given pixel in the given arrays which are grown 
  88  * if not large enough. 
  91 storePixel(pixel
, pmap
, index_return
) 
  94     unsigned int *index_return
; 
 100     if (*index_return
) {                /* this is a transparent pixel! */ 
 104     ncolors 
= pmap
->ncolors
; 
 105     p 
= pmap
->pixels 
+ pmap
->mask_pixel
; 
 106     for (i 
= pmap
->mask_pixel
; i 
< ncolors
; i
++, p
++) 
 107         if ( IS_EQUAL_PIXEL(*p 
, pixel
) ) 
 110         if (ncolors 
>= pmap
->size
) { 
 112             p 
= (Pixel 
*) XpmRealloc(pmap
->pixels
, sizeof(Pixel
) * pmap
->size
); 
 118         (pmap
->pixels
)[ncolors
] = pixel
; 
 126 storeMaskPixel(pixel
, pmap
, index_return
) 
 129     unsigned int *index_return
; 
 131     if (IS_ZERO_PIXEL(pixel
)) { 
 132         if (!pmap
->ncolors
) { 
 134             SET_ZERO_PIXEL((pmap
->pixels
)[0]); 
 135             pmap
->mask_pixel 
= 1; 
 143 /* function call in case of error */ 
 145 #define RETURN(status) \ 
 147       ErrorStatus = status; \ 
 152  * This function scans the given image and stores the found informations in 
 153  * the given XpmImage structure. 
 156 XpmCreateXpmImageFromImage(display
, image
, shapeimage
, 
 157                            xpmimage
, attributes
) 
 162     XpmAttributes 
*attributes
; 
 164     /* variables stored in the XpmAttributes structure */ 
 167     /* variables to return */ 
 169     XpmColor 
*colorTable 
= NULL
; 
 172     /* calculation variables */ 
 173     unsigned int width 
= 0; 
 174     unsigned int height 
= 0; 
 175     unsigned int cppm
;                  /* minimum chars per pixel */ 
 178     /* initialize pmap */ 
 180     pmap
.pixelindex 
= NULL
; 
 181     pmap
.size 
= 256;                    /* should be enough most of the time */ 
 189         width 
= image
->width
; 
 190         height 
= image
->height
; 
 191     } else if (shapeimage
) { 
 192         width 
= shapeimage
->width
; 
 193         height 
= shapeimage
->height
; 
 197      * retrieve information from the XpmAttributes 
 199     if (attributes 
&& (attributes
->valuemask 
& XpmCharsPerPixel
 
 200 /* 3.2 backward compatibility code */ 
 201                        || attributes
->valuemask 
& XpmInfos
)) 
 203         cpp 
= attributes
->cpp
; 
 208         (unsigned int *) XpmCalloc(width 
* height
, sizeof(unsigned int)); 
 209     if (!pmap
.pixelindex
) 
 212     pmap
.pixels 
= (Pixel 
*) XpmMalloc(sizeof(Pixel
) * pmap
.size
); 
 217      * scan shape mask if any 
 221         ErrorStatus 
= PlatformGetImagePixels(display
, shapeimage
, width
, height
, 
 222                                         &pmap
, storeMaskPixel
); 
 224         if (ErrorStatus 
!= XpmSuccess
) 
 229      * scan the image data 
 231      * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use optimized 
 232      * functions, otherwise use slower but sure general one. 
 238         ErrorStatus 
= PlatformGetImagePixels(display
, image
, width
, height
, &pmap
, 
 241         if (ErrorStatus 
!= XpmSuccess
) 
 246      * get rgb values and a string of char, and possibly a name for each 
 250     colorTable 
= (XpmColor 
*) XpmCalloc(pmap
.ncolors
, sizeof(XpmColor
)); 
 254     /* compute the minimal cpp */ 
 255     for (cppm 
= 1, c 
= MAXPRINTABLE
; pmap
.ncolors 
> c
; cppm
++) 
 260     if (pmap
.mask_pixel
) { 
 261         ErrorStatus 
= ScanTransparentColor(colorTable
, cpp
, attributes
); 
 262         if (ErrorStatus 
!= XpmSuccess
) 
 266     ErrorStatus 
= ScanOtherColors(display
, colorTable
, pmap
.ncolors
, 
 267                                   pmap
.pixels
, pmap
.mask_pixel
, cpp
, 
 269     if (ErrorStatus 
!= XpmSuccess
) 
 273      * store found informations in the XpmImage structure 
 275     xpmimage
->width 
= width
; 
 276     xpmimage
->height 
= height
; 
 278     xpmimage
->ncolors 
= pmap
.ncolors
; 
 279     xpmimage
->colorTable 
= colorTable
; 
 280     xpmimage
->data 
= pmap
.pixelindex
; 
 282     XpmFree(pmap
.pixels
); 
 285 /* exit point in case of error, free only locally allocated variables */ 
 288         XpmFree(pmap
.pixelindex
); 
 290         XpmFree(pmap
.pixels
); 
 292         xpmFreeColorTable(colorTable
, pmap
.ncolors
); 
 294     return (ErrorStatus
); 
 298 ScanTransparentColor(color
, cpp
, attributes
) 
 301     XpmAttributes 
*attributes
; 
 304     unsigned int a
, b
, c
; 
 306     /* first get a character string */ 
 308     if (!(s 
= color
->string 
= (char *) XpmMalloc(cpp 
+ 1))) 
 309         return (XpmNoMemory
); 
 310     *s
++ = printable
[c 
= a 
% MAXPRINTABLE
]; 
 311     for (b 
= 1; b 
< cpp
; b
++, s
++) 
 312         *s 
= printable
[c 
= ((a 
- c
) / MAXPRINTABLE
) % MAXPRINTABLE
]; 
 315     /* then retreive related info from the attributes if any */ 
 316     if (attributes 
&& (attributes
->valuemask 
& XpmColorTable
 
 317 /* 3.2 backward compatibility code */ 
 318                        || attributes
->valuemask 
& XpmInfos
) 
 320         && attributes
->mask_pixel 
!= XpmUndefPixel
) { 
 323         char **defaults 
= (char **) color
; 
 324         char **mask_defaults
; 
 326 /* 3.2 backward compatibility code */ 
 327         if (attributes
->valuemask 
& XpmColorTable
) 
 329             mask_defaults 
= (char **) ( 
 330                 attributes
->colorTable 
+ attributes
->mask_pixel
); 
 331 /* 3.2 backward compatibility code */ 
 333             mask_defaults 
= (char **) 
 334                 ((XpmColor 
**) attributes
->colorTable
)[attributes
->mask_pixel
]; 
 336         for (key 
= 1; key 
<= NKEYS
; key
++) { 
 337             if (s 
= mask_defaults
[key
]) { 
 338                 defaults
[key
] = (char *) xpmstrdup(s
); 
 340                     return (XpmNoMemory
); 
 344         color
->c_color 
= (char *) xpmstrdup(TRANSPARENT_COLOR
); 
 346             return (XpmNoMemory
); 
 352 ScanOtherColors(display
, colors
, ncolors
, pixels
, mask
, cpp
, attributes
) 
 359     XpmAttributes 
*attributes
; 
 361     /* variables stored in the XpmAttributes structure */ 
 365     xpmRgbName 
*rgbn 
= NULL
;  
 368     unsigned int i
, j
, c
, i2
; 
 370     XColor 
*xcolors 
= NULL
, *xcolor
; 
 372     XpmColor 
*colorTable
, **oldColorTable 
= NULL
; 
 373     unsigned int ancolors 
= 0; 
 375     unsigned int mask_pixel
; 
 378     /* retrieve information from the XpmAttributes */ 
 379     if (attributes 
&& (attributes
->valuemask 
& XpmColormap
)) 
 380         colormap 
= attributes
->colormap
; 
 382         colormap 
= XDefaultColormap(display
, XDefaultScreen(display
)); 
 383     if (attributes 
&& (attributes
->valuemask 
& XpmRgbFilename
)) 
 384         rgb_fname 
= attributes
->rgb_fname
; 
 388     /* start from the right element */ 
 395     /* first get character strings and rgb values */ 
 396     xcolors 
= (XColor 
*) XpmMalloc(sizeof(XColor
) * ncolors
); 
 398         return (XpmNoMemory
); 
 400     for (i 
= 0, i2 
= mask
, color 
= colors
, xcolor 
= xcolors
; 
 401          i 
< ncolors
; i
++, i2
++, color
++, xcolor
++, pixels
++) { 
 403         if (!(s 
= color
->string 
= (char *) XpmMalloc(cpp 
+ 1))) { 
 405             return (XpmNoMemory
); 
 407         *s
++ = printable
[c 
= i2 
% MAXPRINTABLE
]; 
 408         for (j 
= 1; j 
< cpp
; j
++, s
++) 
 409             *s 
= printable
[c 
= ((i2 
- c
) / MAXPRINTABLE
) % MAXPRINTABLE
]; 
 412         xcolor
->pixel 
= *pixels
; 
 414     XQueryColors(display
, colormap
, xcolors
, ncolors
); 
 416     rgbn_max 
= xpmReadRgbNames(NULL
, NULL
); 
 418     if (attributes 
&& attributes
->valuemask 
& XpmColorTable
) { 
 419         colorTable 
= attributes
->colorTable
; 
 420         ancolors 
= attributes
->ncolors
; 
 421         apixels 
= attributes
->pixels
; 
 422         mask_pixel 
= attributes
->mask_pixel
; 
 424 /* 3.2 backward compatibility code */ 
 425     else if (attributes 
&& attributes
->valuemask 
& XpmInfos
) { 
 426         oldColorTable 
= (XpmColor 
**) attributes
->colorTable
; 
 427         ancolors 
= attributes
->ncolors
; 
 428         apixels 
= attributes
->pixels
; 
 429         mask_pixel 
= attributes
->mask_pixel
; 
 433     for (i 
= 0, color 
= colors
, xcolor 
= xcolors
; i 
< ncolors
; 
 434                                                   i
++, color
++, xcolor
++) { 
 436         /* look for related info from the attributes if any */ 
 439             unsigned int offset 
= 0; 
 441             for (j 
= 0; j 
< ancolors
; j
++) { 
 442                 if (j 
== mask_pixel
) { 
 446                 if (IS_EQUAL_PIXEL( apixels
[j 
- offset
] , xcolor
->pixel
) ) 
 451                 char **defaults 
= (char **) color
; 
 454 /* 3.2 backward compatibility code */ 
 456                     adefaults 
= (char **) oldColorTable
[j
]; 
 459                     adefaults 
= (char **) (colorTable 
+ j
); 
 462                 for (key 
= 1; key 
<= NKEYS
; key
++) { 
 463                     if (s 
= adefaults
[key
]) 
 464                         defaults
[key
] = (char *) xpmstrdup(s
); 
 469             /* if nothing found look for a color name */ 
 472                 colorname 
= xpmGetRgbName(rgbn
, rgbn_max
, xcolor
->red
, 
 473                                           xcolor
->green
, xcolor
->blue
); 
 475                 color
->c_color 
= (char *) xpmstrdup(colorname
); 
 477                 /* at last store the rgb value */ 
 479 //              sprintf(buf, "#%04X%04X%04X", 
 480                 sprintf(buf
, "#%02x%02x%02x", 
 481                         xcolor
->red
, xcolor
->green
, xcolor
->blue
); 
 483                 color
->c_color 
= (char *) xpmstrdup(buf
); 
 485             if (!color
->c_color
) { 
 487                 xpmFreeRgbNames(rgbn
, rgbn_max
); 
 488                 return (XpmNoMemory
); 
 494     xpmFreeRgbNames(rgbn
, rgbn_max
); 
 500 PlatformGetImagePixels(display
, image
, width
, height
, pmap
, storeFunc
) 
 513     iptr 
= pmap
->pixelindex
; 
 515     SelectObject(*display
, image
->bitmap
); 
 516     for (y 
= 0; y 
< height
; y
++) { 
 517         for (x 
= 0; x 
< width
; x
++, iptr
++) { 
 518             pixel 
= GetPixel(*display
, x
, y
); 
 519             if ((*storeFunc
) (pixel
, pmap
, iptr
)) 
 520                 return (XpmNoMemory
);