xpm.c

Go to the documentation of this file.
00001 /* This file contains code for unified image loading from XPM file  */
00002 /********************************************************************/
00003 /* Copyright (c) 2001 Sasha Vasko <sasha at aftercode.net>           */
00004 /********************************************************************/
00005 /*
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 #undef LOCAL_DEBUG
00022 #undef DO_CLOCKING
00023 
00024 #ifdef _WIN32
00025 #include "win32/config.h"
00026 #include <io.h>
00027 #define read _read
00028 #else
00029 #include "config.h"
00030 #endif
00031 
00032 #ifdef HAVE_XPM
00033 
00034 #ifdef HAVE_STDLIB_H
00035 #include <stdlib.h>
00036 #endif
00037 #ifdef HAVE_UNISTD_H
00038 #include <unistd.h>
00039 #endif
00040 #include <ctype.h>
00041 #if TIME_WITH_SYS_TIME
00042 # include <sys/time.h>
00043 # include <time.h>
00044 #else
00045 # if HAVE_SYS_TIME_H
00046 #  include <sys/time.h>
00047 # else
00048 #  include <time.h>
00049 # endif
00050 #endif
00051 #include <sys/stat.h>
00052 #ifdef HAVE_SYS_TYPES_H
00053 #include <sys/types.h>
00054 #endif
00055 #ifdef HAVE_STDDEF_H
00056 #include <stddef.h>
00057 #endif
00058 #include <fcntl.h>
00059 #include <string.h>
00060 
00061 #ifdef HAVE_LIBXPM      /* XPM XPM XPM XPM XPM XPM XPM XPM XPM XPM XPM XPM XPM XPM XPM XPM */
00062 #ifdef HAVE_LIBXPM_X11
00063 #include <X11/xpm.h>
00064 #else
00065 #include <xpm.h>
00066 #endif
00067 #endif
00068 
00069 #ifdef _WIN32
00070 # include "win32/afterbase.h"
00071 #else
00072 # include "afterbase.h"
00073 #endif
00074 #include "asimage.h"
00075 #include "ascmap.h"
00076 #include "xpm.h"
00077 
00078 #define MAXPRINTABLE 92
00079 /* number of printable ascii chars minus \ and " for string compat
00080  * and ? to avoid ANSI trigraphs. */
00081 
00082 static char *printable =
00083 " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
00084 
00085 static struct {
00086         char    *name ;
00087         ARGB32   argb ;
00088         } XpmRGB_Colors[] =
00089 {/* this entire table is taken from libXpm             */
00090  /* Developed by HeDu 3/94 (hedu@cul-ipn.uni-kiel.de)  */
00091     {"AliceBlue", MAKE_ARGB32(255, 240, 248, 255)},
00092     {"AntiqueWhite", MAKE_ARGB32(255, 250, 235, 215)},
00093     {"Aquamarine", MAKE_ARGB32(255, 50, 191, 193)},
00094     {"Azure", MAKE_ARGB32(255, 240, 255, 255)},
00095     {"Beige", MAKE_ARGB32(255, 245, 245, 220)},
00096     {"Bisque", MAKE_ARGB32(255, 255, 228, 196)},
00097     {"Black", MAKE_ARGB32(255, 0, 0, 0)},
00098     {"BlanchedAlmond", MAKE_ARGB32(255, 255, 235, 205)},
00099     {"Blue", MAKE_ARGB32(255, 0, 0, 255)},
00100     {"BlueViolet", MAKE_ARGB32(255, 138, 43, 226)},
00101     {"Brown", MAKE_ARGB32(255, 165, 42, 42)},
00102     {"burlywood", MAKE_ARGB32(255, 222, 184, 135)},
00103     {"CadetBlue", MAKE_ARGB32(255, 95, 146, 158)},
00104     {"chartreuse", MAKE_ARGB32(255, 127, 255, 0)},
00105     {"chocolate", MAKE_ARGB32(255, 210, 105, 30)},
00106     {"Coral", MAKE_ARGB32(255, 255, 114, 86)},
00107     {"CornflowerBlue", MAKE_ARGB32(255, 34, 34, 152)},
00108     {"cornsilk", MAKE_ARGB32(255, 255, 248, 220)},
00109     {"Cyan", MAKE_ARGB32(255, 0, 255, 255)},
00110     {"DarkGoldenrod", MAKE_ARGB32(255, 184, 134, 11)},
00111     {"DarkGreen", MAKE_ARGB32(255, 0, 86, 45)},
00112     {"DarkKhaki", MAKE_ARGB32(255, 189, 183, 107)},
00113     {"DarkOliveGreen", MAKE_ARGB32(255, 85, 86, 47)},
00114     {"DarkOrange", MAKE_ARGB32(255, 255, 140, 0)},
00115     {"DarkOrchid", MAKE_ARGB32(255, 139, 32, 139)},
00116     {"DarkSalmon", MAKE_ARGB32(255, 233, 150, 122)},
00117     {"DarkSeaGreen", MAKE_ARGB32(255, 143, 188, 143)},
00118     {"DarkSlateBlue", MAKE_ARGB32(255, 56, 75, 102)},
00119     {"DarkSlateGray", MAKE_ARGB32(255, 47, 79, 79)},
00120     {"DarkTurquoise", MAKE_ARGB32(255, 0, 166, 166)},
00121     {"DarkViolet", MAKE_ARGB32(255, 148, 0, 211)},
00122     {"DeepPink", MAKE_ARGB32(255, 255, 20, 147)},
00123     {"DeepSkyBlue", MAKE_ARGB32(255, 0, 191, 255)},
00124     {"DimGray", MAKE_ARGB32(255, 84, 84, 84)},
00125     {"DodgerBlue", MAKE_ARGB32(255, 30, 144, 255)},
00126     {"Firebrick", MAKE_ARGB32(255, 142, 35, 35)},
00127     {"FloralWhite", MAKE_ARGB32(255, 255, 250, 240)},
00128     {"ForestGreen", MAKE_ARGB32(255, 80, 159, 105)},
00129     {"gainsboro", MAKE_ARGB32(255, 220, 220, 220)},
00130     {"GhostWhite", MAKE_ARGB32(255, 248, 248, 255)},
00131     {"Gold", MAKE_ARGB32(255, 218, 170, 0)},
00132     {"Goldenrod", MAKE_ARGB32(255, 239, 223, 132)},
00133     {"Gray", MAKE_ARGB32(255, 126, 126, 126)},
00134     {"Gray0", MAKE_ARGB32(255, 0, 0, 0)},
00135     {"Gray1", MAKE_ARGB32(255, 3, 3, 3)},
00136     {"Gray10", MAKE_ARGB32(255, 26, 26, 26)},
00137     {"Gray100", MAKE_ARGB32(255, 255, 255, 255)},
00138     {"Gray11", MAKE_ARGB32(255, 28, 28, 28)},
00139     {"Gray12", MAKE_ARGB32(255, 31, 31, 31)},
00140     {"Gray13", MAKE_ARGB32(255, 33, 33, 33)},
00141     {"Gray14", MAKE_ARGB32(255, 36, 36, 36)},
00142     {"Gray15", MAKE_ARGB32(255, 38, 38, 38)},
00143     {"Gray16", MAKE_ARGB32(255, 41, 41, 41)},
00144     {"Gray17", MAKE_ARGB32(255, 43, 43, 43)},
00145     {"Gray18", MAKE_ARGB32(255, 46, 46, 46)},
00146     {"Gray19", MAKE_ARGB32(255, 48, 48, 48)},
00147     {"Gray2", MAKE_ARGB32(255, 5, 5, 5)},
00148     {"Gray20", MAKE_ARGB32(255, 51, 51, 51)},
00149     {"Gray21", MAKE_ARGB32(255, 54, 54, 54)},
00150     {"Gray22", MAKE_ARGB32(255, 56, 56, 56)},
00151     {"Gray23", MAKE_ARGB32(255, 59, 59, 59)},
00152     {"Gray24", MAKE_ARGB32(255, 61, 61, 61)},
00153     {"Gray25", MAKE_ARGB32(255, 64, 64, 64)},
00154     {"Gray26", MAKE_ARGB32(255, 66, 66, 66)},
00155     {"Gray27", MAKE_ARGB32(255, 69, 69, 69)},
00156     {"Gray28", MAKE_ARGB32(255, 71, 71, 71)},
00157     {"Gray29", MAKE_ARGB32(255, 74, 74, 74)},
00158     {"Gray3", MAKE_ARGB32(255, 8, 8, 8)},
00159     {"Gray30", MAKE_ARGB32(255, 77, 77, 77)},
00160     {"Gray31", MAKE_ARGB32(255, 79, 79, 79)},
00161     {"Gray32", MAKE_ARGB32(255, 82, 82, 82)},
00162     {"Gray33", MAKE_ARGB32(255, 84, 84, 84)},
00163     {"Gray34", MAKE_ARGB32(255, 87, 87, 87)},
00164     {"Gray35", MAKE_ARGB32(255, 89, 89, 89)},
00165     {"Gray36", MAKE_ARGB32(255, 92, 92, 92)},
00166     {"Gray37", MAKE_ARGB32(255, 94, 94, 94)},
00167     {"Gray38", MAKE_ARGB32(255, 97, 97, 97)},
00168     {"Gray39", MAKE_ARGB32(255, 99, 99, 99)},
00169     {"Gray4", MAKE_ARGB32(255, 10, 10, 10)},
00170     {"Gray40", MAKE_ARGB32(255, 102, 102, 102)},
00171     {"Gray41", MAKE_ARGB32(255, 105, 105, 105)},
00172     {"Gray42", MAKE_ARGB32(255, 107, 107, 107)},
00173     {"Gray43", MAKE_ARGB32(255, 110, 110, 110)},
00174     {"Gray44", MAKE_ARGB32(255, 112, 112, 112)},
00175     {"Gray45", MAKE_ARGB32(255, 115, 115, 115)},
00176     {"Gray46", MAKE_ARGB32(255, 117, 117, 117)},
00177     {"Gray47", MAKE_ARGB32(255, 120, 120, 120)},
00178     {"Gray48", MAKE_ARGB32(255, 122, 122, 122)},
00179     {"Gray49", MAKE_ARGB32(255, 125, 125, 125)},
00180     {"Gray5", MAKE_ARGB32(255, 13, 13, 13)},
00181     {"Gray50", MAKE_ARGB32(255, 127, 127, 127)},
00182     {"Gray51", MAKE_ARGB32(255, 130, 130, 130)},
00183     {"Gray52", MAKE_ARGB32(255, 133, 133, 133)},
00184     {"Gray53", MAKE_ARGB32(255, 135, 135, 135)},
00185     {"Gray54", MAKE_ARGB32(255, 138, 138, 138)},
00186     {"Gray55", MAKE_ARGB32(255, 140, 140, 140)},
00187     {"Gray56", MAKE_ARGB32(255, 143, 143, 143)},
00188     {"Gray57", MAKE_ARGB32(255, 145, 145, 145)},
00189     {"Gray58", MAKE_ARGB32(255, 148, 148, 148)},
00190     {"Gray59", MAKE_ARGB32(255, 150, 150, 150)},
00191     {"Gray6", MAKE_ARGB32(255, 15, 15, 15)},
00192     {"Gray60", MAKE_ARGB32(255, 153, 153, 153)},
00193     {"Gray61", MAKE_ARGB32(255, 156, 156, 156)},
00194     {"Gray62", MAKE_ARGB32(255, 158, 158, 158)},
00195     {"Gray63", MAKE_ARGB32(255, 161, 161, 161)},
00196     {"Gray64", MAKE_ARGB32(255, 163, 163, 163)},
00197     {"Gray65", MAKE_ARGB32(255, 166, 166, 166)},
00198     {"Gray66", MAKE_ARGB32(255, 168, 168, 168)},
00199     {"Gray67", MAKE_ARGB32(255, 171, 171, 171)},
00200     {"Gray68", MAKE_ARGB32(255, 173, 173, 173)},
00201     {"Gray69", MAKE_ARGB32(255, 176, 176, 176)},
00202     {"Gray7", MAKE_ARGB32(255, 18, 18, 18)},
00203     {"Gray70", MAKE_ARGB32(255, 179, 179, 179)},
00204     {"Gray71", MAKE_ARGB32(255, 181, 181, 181)},
00205     {"Gray72", MAKE_ARGB32(255, 184, 184, 184)},
00206     {"Gray73", MAKE_ARGB32(255, 186, 186, 186)},
00207     {"Gray74", MAKE_ARGB32(255, 189, 189, 189)},
00208     {"Gray75", MAKE_ARGB32(255, 191, 191, 191)},
00209     {"Gray76", MAKE_ARGB32(255, 194, 194, 194)},
00210     {"Gray77", MAKE_ARGB32(255, 196, 196, 196)},
00211     {"Gray78", MAKE_ARGB32(255, 199, 199, 199)},
00212     {"Gray79", MAKE_ARGB32(255, 201, 201, 201)},
00213     {"Gray8", MAKE_ARGB32(255, 20, 20, 20)},
00214     {"Gray80", MAKE_ARGB32(255, 204, 204, 204)},
00215     {"Gray81", MAKE_ARGB32(255, 207, 207, 207)},
00216     {"Gray82", MAKE_ARGB32(255, 209, 209, 209)},
00217     {"Gray83", MAKE_ARGB32(255, 212, 212, 212)},
00218     {"Gray84", MAKE_ARGB32(255, 214, 214, 214)},
00219     {"Gray85", MAKE_ARGB32(255, 217, 217, 217)},
00220     {"Gray86", MAKE_ARGB32(255, 219, 219, 219)},
00221     {"Gray87", MAKE_ARGB32(255, 222, 222, 222)},
00222     {"Gray88", MAKE_ARGB32(255, 224, 224, 224)},
00223     {"Gray89", MAKE_ARGB32(255, 227, 227, 227)},
00224     {"Gray9", MAKE_ARGB32(255, 23, 23, 23)},
00225     {"Gray90", MAKE_ARGB32(255, 229, 229, 229)},
00226     {"Gray91", MAKE_ARGB32(255, 232, 232, 232)},
00227     {"Gray92", MAKE_ARGB32(255, 235, 235, 235)},
00228     {"Gray93", MAKE_ARGB32(255, 237, 237, 237)},
00229     {"Gray94", MAKE_ARGB32(255, 240, 240, 240)},
00230     {"Gray95", MAKE_ARGB32(255, 242, 242, 242)},
00231     {"Gray96", MAKE_ARGB32(255, 245, 245, 245)},
00232     {"Gray97", MAKE_ARGB32(255, 247, 247, 247)},
00233     {"Gray98", MAKE_ARGB32(255, 250, 250, 250)},
00234     {"Gray99", MAKE_ARGB32(255, 252, 252, 252)},
00235     {"Green", MAKE_ARGB32(255, 0, 255, 0)},
00236     {"GreenYellow", MAKE_ARGB32(255, 173, 255, 47)},
00237     {"honeydew", MAKE_ARGB32(255, 240, 255, 240)},
00238     {"HotPink", MAKE_ARGB32(255, 255, 105, 180)},
00239     {"IndianRed", MAKE_ARGB32(255, 107, 57, 57)},
00240     {"ivory", MAKE_ARGB32(255, 255, 255, 240)},
00241     {"Khaki", MAKE_ARGB32(255, 179, 179, 126)},
00242     {"lavender", MAKE_ARGB32(255, 230, 230, 250)},
00243     {"LavenderBlush", MAKE_ARGB32(255, 255, 240, 245)},
00244     {"LawnGreen", MAKE_ARGB32(255, 124, 252, 0)},
00245     {"LemonChiffon", MAKE_ARGB32(255, 255, 250, 205)},
00246     {"LightBlue", MAKE_ARGB32(255, 176, 226, 255)},
00247     {"LightCoral", MAKE_ARGB32(255, 240, 128, 128)},
00248     {"LightCyan", MAKE_ARGB32(255, 224, 255, 255)},
00249     {"LightGoldenrod", MAKE_ARGB32(255, 238, 221, 130)},
00250     {"LightGoldenrodYellow", MAKE_ARGB32(255, 250, 250, 210)},
00251     {"LightGray", MAKE_ARGB32(255, 168, 168, 168)},
00252     {"LightPink", MAKE_ARGB32(255, 255, 182, 193)},
00253     {"LightSalmon", MAKE_ARGB32(255, 255, 160, 122)},
00254     {"LightSeaGreen", MAKE_ARGB32(255, 32, 178, 170)},
00255     {"LightSkyBlue", MAKE_ARGB32(255, 135, 206, 250)},
00256     {"LightSlateBlue", MAKE_ARGB32(255, 132, 112, 255)},
00257     {"LightSlateGray", MAKE_ARGB32(255, 119, 136, 153)},
00258     {"LightSteelBlue", MAKE_ARGB32(255, 124, 152, 211)},
00259     {"LightYellow", MAKE_ARGB32(255, 255, 255, 224)},
00260     {"LimeGreen", MAKE_ARGB32(255, 0, 175, 20)},
00261     {"linen", MAKE_ARGB32(255, 250, 240, 230)},
00262     {"Magenta", MAKE_ARGB32(255, 255, 0, 255)},
00263     {"Maroon", MAKE_ARGB32(255, 143, 0, 82)},
00264     {"MediumAquamarine", MAKE_ARGB32(255, 0, 147, 143)},
00265     {"MediumBlue", MAKE_ARGB32(255, 50, 50, 204)},
00266     {"MediumForestGreen", MAKE_ARGB32(255, 50, 129, 75)},
00267     {"MediumGoldenrod", MAKE_ARGB32(255, 209, 193, 102)},
00268     {"MediumOrchid", MAKE_ARGB32(255, 189, 82, 189)},
00269     {"MediumPurple", MAKE_ARGB32(255, 147, 112, 219)},
00270     {"MediumSeaGreen", MAKE_ARGB32(255, 52, 119, 102)},
00271     {"MediumSlateBlue", MAKE_ARGB32(255, 106, 106, 141)},
00272     {"MediumSpringGreen", MAKE_ARGB32(255, 35, 142, 35)},
00273     {"MediumTurquoise", MAKE_ARGB32(255, 0, 210, 210)},
00274     {"MediumVioletRed", MAKE_ARGB32(255, 213, 32, 121)},
00275     {"MidnightBlue", MAKE_ARGB32(255, 47, 47, 100)},
00276     {"MintCream", MAKE_ARGB32(255, 245, 255, 250)},
00277     {"MistyRose", MAKE_ARGB32(255, 255, 228, 225)},
00278     {"moccasin", MAKE_ARGB32(255, 255, 228, 181)},
00279     {"NavajoWhite", MAKE_ARGB32(255, 255, 222, 173)},
00280     {"Navy", MAKE_ARGB32(255, 35, 35, 117)},
00281     {"NavyBlue", MAKE_ARGB32(255, 35, 35, 117)},
00282     {"None", MAKE_ARGB32(0, 0, 0, 1)},
00283     {"OldLace", MAKE_ARGB32(255, 253, 245, 230)},
00284     {"OliveDrab", MAKE_ARGB32(255, 107, 142, 35)},
00285     {"Orange", MAKE_ARGB32(255, 255, 135, 0)},
00286     {"OrangeRed", MAKE_ARGB32(255, 255, 69, 0)},
00287     {"Orchid", MAKE_ARGB32(255, 239, 132, 239)},
00288     {"PaleGoldenrod", MAKE_ARGB32(255, 238, 232, 170)},
00289     {"PaleGreen", MAKE_ARGB32(255, 115, 222, 120)},
00290     {"PaleTurquoise", MAKE_ARGB32(255, 175, 238, 238)},
00291     {"PaleVioletRed", MAKE_ARGB32(255, 219, 112, 147)},
00292     {"PapayaWhip", MAKE_ARGB32(255, 255, 239, 213)},
00293     {"PeachPuff", MAKE_ARGB32(255, 255, 218, 185)},
00294     {"peru", MAKE_ARGB32(255, 205, 133, 63)},
00295     {"Pink", MAKE_ARGB32(255, 255, 181, 197)},
00296     {"Plum", MAKE_ARGB32(255, 197, 72, 155)},
00297     {"PowderBlue", MAKE_ARGB32(255, 176, 224, 230)},
00298     {"purple", MAKE_ARGB32(255, 160, 32, 240)},
00299     {"Red", MAKE_ARGB32(255, 255, 0, 0)},
00300     {"RosyBrown", MAKE_ARGB32(255, 188, 143, 143)},
00301     {"RoyalBlue", MAKE_ARGB32(255, 65, 105, 225)},
00302     {"SaddleBrown", MAKE_ARGB32(255, 139, 69, 19)},
00303     {"Salmon", MAKE_ARGB32(255, 233, 150, 122)},
00304     {"SandyBrown", MAKE_ARGB32(255, 244, 164, 96)},
00305     {"SeaGreen", MAKE_ARGB32(255, 82, 149, 132)},
00306     {"seashell", MAKE_ARGB32(255, 255, 245, 238)},
00307     {"Sienna", MAKE_ARGB32(255, 150, 82, 45)},
00308     {"SkyBlue", MAKE_ARGB32(255, 114, 159, 255)},
00309     {"SlateBlue", MAKE_ARGB32(255, 126, 136, 171)},
00310     {"SlateGray", MAKE_ARGB32(255, 112, 128, 144)},
00311     {"snow", MAKE_ARGB32(255, 255, 250, 250)},
00312     {"SpringGreen", MAKE_ARGB32(255, 65, 172, 65)},
00313     {"SteelBlue", MAKE_ARGB32(255, 84, 112, 170)},
00314     {"Tan", MAKE_ARGB32(255, 222, 184, 135)},
00315     {"Thistle", MAKE_ARGB32(255, 216, 191, 216)},
00316     {"tomato", MAKE_ARGB32(255, 255, 99, 71)},
00317     {"Transparent", MAKE_ARGB32(0, 0, 0, 1)},
00318     {"Turquoise", MAKE_ARGB32(255, 25, 204, 223)},
00319     {"Violet", MAKE_ARGB32(255, 156, 62, 206)},
00320     {"VioletRed", MAKE_ARGB32(255, 243, 62, 150)},
00321     {"Wheat", MAKE_ARGB32(255, 245, 222, 179)},
00322     {"White", MAKE_ARGB32(255, 255, 255, 255)},
00323     {"WhiteSmoke", MAKE_ARGB32(255, 245, 245, 245)},
00324     {"Yellow", MAKE_ARGB32(255, 255, 255, 0)},
00325     {"YellowGreen", MAKE_ARGB32(255, 50, 216, 56)},
00326     {NULL,0}
00327 };
00328 
00329 /****************************************************************
00330  * Low level parsing code :
00331  ****************************************************************/
00332 static inline char
00333 get_xpm_char( ASXpmFile *xpm_file )
00334 {
00335 #ifdef HAVE_LIBXPM
00336         return '\0';
00337 #else
00338         char c;
00339         if( xpm_file->curr_byte >= xpm_file->bytes_in )
00340         {
00341                 if( xpm_file->bytes_in > AS_XPM_BUFFER_UNDO )
00342                 {
00343                         register char* src = &(xpm_file->buffer[xpm_file->bytes_in-AS_XPM_BUFFER_UNDO]);
00344                         register char* dst = &(xpm_file->buffer[0]);
00345                         register int i;
00346                         for( i = 0 ; i < AS_XPM_BUFFER_UNDO ; i++ )
00347                                 dst[i] = src[i];
00348 /*                      xpm_file->bytes_in = AS_XPM_BUFFER_UNDO+fread( &(xpm_file->buffer[AS_XPM_BUFFER_UNDO]), 1, AS_XPM_BUFFER_SIZE, xpm_file->fp );*/
00349                         xpm_file->bytes_in = xpm_file->data ?  AS_XPM_BUFFER_UNDO + strlen(*xpm_file->data) : 
00350                                  AS_XPM_BUFFER_UNDO+read( xpm_file->fd, &(xpm_file->buffer[AS_XPM_BUFFER_UNDO]), AS_XPM_BUFFER_SIZE );
00351                         xpm_file->curr_byte = AS_XPM_BUFFER_UNDO ;
00352                 }
00353                 if( xpm_file->bytes_in <= AS_XPM_BUFFER_UNDO )
00354                 {
00355                         xpm_file->parse_state = XPM_Outside ;
00356                         return '\0';
00357                 }
00358         }
00359         c = xpm_file->buffer[xpm_file->curr_byte];
00360 /*      fprintf( stderr, "curr byte = %d ( of %d ), char = %c\n", xpm_file->curr_byte, xpm_file->bytes_in, c ); */
00361 
00362         xpm_file->curr_byte++;
00363         return c;
00364 #endif
00365 }
00366 
00367 static inline void
00368 unget_xpm_char( ASXpmFile *xpm_file, char c )
00369 {
00370 #ifndef HAVE_LIBXPM
00371         if( xpm_file->curr_byte > 0 )
00372         {
00373                 xpm_file->curr_byte--;
00374                 xpm_file->buffer[xpm_file->curr_byte] = c;
00375         }
00376 #endif
00377 }
00378 
00379 static inline void
00380 skip_xpm_comments( ASXpmFile *xpm_file )
00381 {
00382         char c;
00383         if((c=get_xpm_char(xpm_file)) != '*')
00384                 unget_xpm_char(xpm_file, c);
00385         else
00386         {
00387                 xpm_file->parse_state = XPM_InComments ;
00388                 while( xpm_file->parse_state == XPM_InComments )
00389                 {
00390                         c = get_xpm_char(xpm_file);
00391                         if( c == '*' )
00392                                 if( (c=get_xpm_char(xpm_file)) == '/' )
00393                                         xpm_file->parse_state--;
00394                 }
00395         }
00396 }
00397 
00398 static Bool
00399 seek_next_xpm_string( ASXpmFile *xpm_file )
00400 {
00401         while( xpm_file->parse_state == XPM_InImage )
00402         {
00403                 register char c;
00404                 c = get_xpm_char(xpm_file);
00405                 if( c == '/')
00406                         skip_xpm_comments( xpm_file );
00407                 else if( c == '"')
00408                         xpm_file->parse_state = XPM_InString;
00409         }
00410         return (xpm_file->parse_state >= XPM_InString);
00411 }
00412 
00413 static Bool
00414 seek_next_xpm_image( ASXpmFile *xpm_file )
00415 {
00416         while( xpm_file->parse_state == XPM_InFile )
00417         {
00418                 register char c;
00419                 c = get_xpm_char(xpm_file);
00420                 if( c == '/')
00421                         skip_xpm_comments( xpm_file );
00422                 else if( c == '{')
00423                         xpm_file->parse_state = XPM_InImage;
00424         }
00425         return (xpm_file->parse_state >= XPM_InImage);
00426 }
00427 
00428 static Bool
00429 read_next_xpm_string( ASXpmFile *xpm_file )
00430 {
00431         char c;
00432         int i = 0;
00433         while( xpm_file->parse_state == XPM_InString )
00434         {
00435                 c=get_xpm_char(xpm_file);
00436                 if( c == '"' )
00437                 {
00438                         xpm_file->parse_state = XPM_InImage ;
00439                         c = '\0';
00440                 }
00441 
00442                 if( i >= (int)xpm_file->str_buf_size )
00443                 {
00444                         xpm_file->str_buf = realloc( xpm_file->str_buf, xpm_file->str_buf_size+16+(xpm_file->str_buf_size>>2));
00445                         xpm_file->str_buf_size += 16+(xpm_file->str_buf_size>>2) ;
00446                 }
00447                 xpm_file->str_buf[i++] = c;
00448         }
00449    xpm_file->curr_img_line++;
00450 
00451         return True;
00452 }
00453 
00454 #ifndef HAVE_LIBXPM
00455 static Bool
00456 parse_xpm_cmap_entry( ASXpmFile *xpm_file, char **colornames )
00457 {
00458         register char *ptr ;
00459         int key ;
00460         Bool success = False ;
00461 
00462         if( xpm_file == NULL || xpm_file->str_buf == NULL )
00463                 return False;
00464         for( key =0 ; key < 6 ; ++key )
00465                 colornames[key] = NULL ;
00466 
00467         ptr = xpm_file->str_buf+xpm_file->bpp ;
00468         key = -1;
00469         do
00470         {
00471         while( !isspace((int)*ptr) && *ptr != '\0' ) ++ptr;
00472         while( isspace((int)*ptr) ) ++ptr;
00473                 if( *ptr )
00474                 {
00475                         if( key >= 0 )
00476                         {
00477                                 colornames[key] = ptr ;
00478                                 key = -1 ;
00479                                 success = True;
00480                         }else
00481                         {
00482                         if( *ptr == 'c' )                               /* key #5: color visual */
00483                                         key = 5;
00484                                 else
00485                                 {
00486                                         if( *ptr == 's' )                               /* key #1: symbol */
00487                                                 key = 1;
00488                                 else if( *ptr == 'm' )                          /* key #2: mono visual */
00489                                                 key = 2;
00490                                 else if( *ptr == 'g' )                          /* key #4: gray visual */
00491                                                 key = 4;
00492                                         else
00493                                                 key = 0;
00494                                 }
00495                         }
00496                 }
00497         }while( *ptr );
00498         return success;
00499 }
00500 #endif
00501 /*************************************************************************
00502  * High level xpm reading interface ;
00503  *************************************************************************/
00504 void
00505 close_xpm_file( ASXpmFile **xpm_file )
00506 {
00507         if( xpm_file )
00508                 if( *xpm_file )
00509                 {
00510                         if( (*xpm_file)->fd )
00511                                 close( (*xpm_file)->fd );
00512                         if( (*xpm_file)->str_buf && !(*xpm_file)->data)
00513                                 free( (*xpm_file)->str_buf );
00514 #ifdef HAVE_LIBXPM
00515                         XpmFreeXpmImage (&((*xpm_file)->xpmImage));
00516 #else
00517                         if( (*xpm_file)->buffer && !(*xpm_file)->data)
00518                                 free( (*xpm_file)->buffer );
00519 #endif
00520                         free_scanline(&((*xpm_file)->scl), True);
00521                         if( (*xpm_file)->cmap )
00522                                 free( (*xpm_file)->cmap );
00523                         if( (*xpm_file)->cmap2 )
00524                         {
00525                                 register int i ;
00526                                 for( i = 0 ; i < 256 ; i++ )
00527                                         if( (*xpm_file)->cmap2[i] )
00528                                                 free( (*xpm_file)->cmap2[i] );
00529                                 free( (*xpm_file)->cmap2 );
00530                         }
00531                         if( (*xpm_file)->cmap_name_xref )
00532                                 destroy_ashash( &((*xpm_file)->cmap_name_xref) );
00533 #if 0
00534                         memset( *xpm_file, 0x00, sizeof(ASXpmFile));
00535 #endif
00536                         free( *xpm_file );
00537                         *xpm_file = NULL ;
00538                 }
00539 }
00540 
00541 ASXpmFile*
00542 open_xpm_file( const char *realfilename )
00543 {
00544         ASXpmFile *xpm_file = NULL;
00545         if( realfilename )
00546         {
00547                 Bool success = False ;
00548                 int fd ;
00549                 xpm_file = safecalloc( 1, sizeof(ASXpmFile));
00550 #ifndef HAVE_LIBXPM
00551                 fd = open( realfilename, O_RDONLY );
00552                 if( fd >= 0 )
00553                 {
00554                         xpm_file->fd = fd;
00555                         xpm_file->parse_state = XPM_InFile ;
00556                         xpm_file->buffer = safemalloc(AS_XPM_BUFFER_UNDO+AS_XPM_BUFFER_SIZE+1);
00557          xpm_file->data = 0;
00558 /*                      xpm_file->bytes_in = AS_XPM_BUFFER_UNDO+fread( &(xpm_file->buffer[AS_XPM_BUFFER_UNDO]), 1, AS_XPM_BUFFER_SIZE, fp ); */
00559                         xpm_file->bytes_in = AS_XPM_BUFFER_UNDO+read( fd, &(xpm_file->buffer[AS_XPM_BUFFER_UNDO]),  AS_XPM_BUFFER_SIZE );
00560                         xpm_file->curr_byte = AS_XPM_BUFFER_UNDO ;
00561                         if (get_xpm_string( xpm_file ) == XPM_Success)
00562                                 success = parse_xpm_header( xpm_file );
00563                 }
00564 #else                                          /* libXpm interface : */
00565                 if( XpmReadFileToXpmImage ((char *)realfilename, &(xpm_file->xpmImage), NULL) == XpmSuccess)
00566                 {
00567                         fd = NULL ;
00568                         xpm_file->width = xpm_file->xpmImage.width;
00569                         xpm_file->height= xpm_file->xpmImage.height;
00570                         xpm_file->cmap_size = xpm_file->xpmImage.ncolors;
00571                         xpm_file->bpp = xpm_file->xpmImage.cpp;
00572                         success = True;
00573                 }
00574 #endif
00575                 if( !success ) {
00576                         close_xpm_file( &xpm_file );
00577          return NULL;
00578                 } else
00579                 {
00580                         if( xpm_file->width > MAX_IMPORT_IMAGE_SIZE )
00581                                 xpm_file->width = MAX_IMPORT_IMAGE_SIZE ;
00582                         if( xpm_file->height > MAX_IMPORT_IMAGE_SIZE )
00583                                 xpm_file->height = MAX_IMPORT_IMAGE_SIZE ;
00584                         if( xpm_file->bpp > MAX_XPM_BPP )
00585                                 xpm_file->bpp = MAX_XPM_BPP;
00586                         prepare_scanline( xpm_file->width, 0, &(xpm_file->scl), False );
00587                 }
00588         }
00589         return xpm_file ;
00590 }
00591 
00592 
00593 ASXpmFile*
00594 open_xpm_data( const char **data )
00595 {
00596         ASXpmFile *xpm_file = NULL;
00597         if( data )
00598         {
00599                 Bool success = False ;
00600 
00601                 xpm_file = safecalloc( 1, sizeof(ASXpmFile));
00602                 xpm_file->data = (char**)data ;
00603                 xpm_file->parse_state = XPM_InFile ;
00604                 xpm_file->buffer = 0;
00605                 xpm_file->curr_byte = AS_XPM_BUFFER_UNDO ;
00606                 if( get_xpm_string( xpm_file ) == XPM_Success) {
00607                         success = parse_xpm_header( xpm_file );
00608                }
00609 
00610                 if( !success ) {
00611                   close_xpm_file( &xpm_file );
00612                   return NULL;
00613                 } else
00614                 {
00615                         if( xpm_file->width > MAX_IMPORT_IMAGE_SIZE )
00616                                 xpm_file->width = MAX_IMPORT_IMAGE_SIZE ;
00617                         if( xpm_file->height > MAX_IMPORT_IMAGE_SIZE )
00618                                 xpm_file->height = MAX_IMPORT_IMAGE_SIZE ;
00619                         if( xpm_file->bpp > MAX_XPM_BPP )
00620                                 xpm_file->bpp = MAX_XPM_BPP;
00621                         prepare_scanline( xpm_file->width, 0, &(xpm_file->scl), False );
00622                 }
00623         }
00624         return xpm_file ;
00625 }
00626 
00627 
00628 ASXpmFile*
00629 open_xpm_raw_data( const char *data )
00630 {
00631         ASXpmFile *xpm_file = NULL;
00632         if( data )
00633         {
00634                 Bool success = False ;
00635 
00636                 xpm_file = safecalloc( 1, sizeof(ASXpmFile));
00637                 xpm_file->data = (char**)&data ;
00638                 xpm_file->parse_state = XPM_InFile ;
00639                 xpm_file->buffer = (char*)data;
00640                 xpm_file->curr_byte = AS_XPM_BUFFER_UNDO ;
00641       xpm_file->bytes_in = AS_XPM_BUFFER_UNDO + strlen(data);
00642                 if( get_xpm_string( xpm_file )  == XPM_Success)
00643                         success = parse_xpm_header( xpm_file );
00644 
00645                 if( !success ) {
00646                         close_xpm_file( &xpm_file );
00647          return NULL;
00648                 } else
00649                 {
00650                         if( xpm_file->width > MAX_IMPORT_IMAGE_SIZE )
00651                                 xpm_file->width = MAX_IMPORT_IMAGE_SIZE ;
00652                         if( xpm_file->height > MAX_IMPORT_IMAGE_SIZE )
00653                                 xpm_file->height = MAX_IMPORT_IMAGE_SIZE ;
00654                         if( xpm_file->bpp > MAX_XPM_BPP )
00655                                 xpm_file->bpp = MAX_XPM_BPP;
00656                         prepare_scanline( xpm_file->width, 0, &(xpm_file->scl), False );
00657                 }
00658       xpm_file->curr_img_line = 0;
00659         }
00660         return xpm_file ;
00661 }
00662 
00663 ASXpmStatus
00664 get_xpm_string( ASXpmFile *xpm_file )
00665 {
00666 
00667    if( xpm_file == NULL )
00668       return XPM_Error;
00669    if( !xpm_file->buffer )
00670    {
00671       xpm_file->str_buf = xpm_file->data[xpm_file->curr_img_line];
00672       xpm_file->str_buf_size = 0 ;
00673       xpm_file->curr_img_line++;
00674       if( xpm_file->str_buf == NULL )
00675          return XPM_EndOfFile;
00676    }else
00677    {
00678       if( xpm_file->parse_state < XPM_InFile )
00679          return XPM_EndOfFile;
00680       if( xpm_file->parse_state < XPM_InImage )
00681       {
00682          if( !seek_next_xpm_image( xpm_file ) )
00683             return XPM_EndOfFile;
00684       }
00685       if( !seek_next_xpm_string( xpm_file ) )
00686       {
00687          xpm_file->curr_img++;
00688          return XPM_EndOfImage;
00689       }
00690       if( !read_next_xpm_string( xpm_file ))
00691          return XPM_Error;
00692       xpm_file->curr_img_line++;
00693    }
00694    return XPM_Success;
00695 }
00696 
00697 Bool
00698 parse_xpm_header( ASXpmFile *xpm_file )
00699 {
00700         register char *ptr ;
00701         if( xpm_file == NULL || xpm_file->str_buf == NULL )
00702                 return False;
00703 
00704         ptr = xpm_file->str_buf ;
00705         while( isspace((int)*ptr) ) ++ptr;
00706         if( *ptr == '\0' )
00707                 return False;
00708         xpm_file->width = atoi( ptr );
00709         while( !isspace((int)*ptr) && *ptr != '\0' ) ++ptr;
00710         while( isspace((int)*ptr) ) ++ptr;
00711         if( *ptr == '\0' )
00712                 return False;
00713         xpm_file->height = atoi( ptr );
00714         while( !isspace((int)*ptr) && *ptr != '\0' ) ++ptr;
00715         while( isspace((int)*ptr) ) ++ptr;
00716         if( *ptr == '\0' )
00717                 return False;
00718         xpm_file->cmap_size = atoi( ptr );
00719         while( !isspace((int)*ptr) && *ptr != '\0' ) ++ptr;
00720         while( isspace((int)*ptr) ) ++ptr;
00721         if( *ptr == '\0' )
00722                 return False;
00723         xpm_file->bpp = atoi( ptr );
00724         return True;
00725 }
00726 
00727 ASImage *
00728 create_xpm_image( ASXpmFile *xpm_file, int compression )
00729 {
00730         ASImage *im = NULL;
00731         if( xpm_file != NULL && xpm_file->width > 0 && xpm_file->height > 0 )
00732         {
00733                 im = create_asimage( xpm_file->width, xpm_file->height, compression );
00734         }
00735         return im;
00736 }
00737 
00738 static ARGB32
00739 lookup_xpm_color( char **colornames, ASHashTable *xpm_color_names )
00740 {
00741     ARGB32 color = 0;
00742         register int key = 5 ;
00743         do
00744         {
00745                 if( colornames[key] )
00746                 {
00747                         if( *(colornames[key]) != '#' )
00748                         {
00749                                 ASHashData hdata ;
00750                 if( get_hash_item( xpm_color_names, AS_HASHABLE(colornames[key]), &hdata.vptr ) == ASH_Success )
00751                                 {
00752                     color = hdata.c32 ;
00753                                         LOCAL_DEBUG_OUT(" xpm color \"%s\" matched into 0x%lX", colornames[key], color );
00754                                         break;
00755                                 }
00756                         }
00757                         if( parse_argb_color( colornames[key], &color ) != colornames[key] )
00758                         {
00759                                 LOCAL_DEBUG_OUT(" xpm color \"%s\" parsed into 0x%lX", colornames[key], color );
00760                                 break;
00761                         }
00762                         LOCAL_DEBUG_OUT(" xpm color \"%s\" is invalid :(", colornames[key] );
00763                         /* unknown color - leaving it at 0 - that will make it transparent */
00764                 }
00765         }while ( --key > 0);
00766         return color;
00767 }
00768 
00769 void
00770 string_value_destroy (ASHashableValue value, void *data)
00771 {
00772         if ((char*)value != NULL)
00773                 free ((char*)value);
00774 }
00775 
00776 Bool
00777 build_xpm_colormap( ASXpmFile *xpm_file )
00778 {
00779         size_t real_cmap_size ;
00780         size_t i ;
00781 #ifdef HAVE_LIBXPM
00782         XpmColor *xpm_cmap = (xpm_file)?xpm_file->xpmImage.colorTable: NULL ;
00783 #endif
00784         static ASHashTable *xpm_color_names = NULL ;
00785 
00786         if( xpm_file == NULL )
00787         {
00788                 destroy_ashash(&xpm_color_names);
00789                 return False;
00790         }
00791 
00792         if( xpm_file->cmap_name_xref )
00793                 destroy_ashash( &(xpm_file->cmap_name_xref) );
00794         if( xpm_file->cmap )
00795         {
00796                 free( xpm_file->cmap );
00797                 xpm_file->cmap = NULL;
00798         }
00799         real_cmap_size = xpm_file->cmap_size;
00800 #ifdef HAVE_LIBXPM
00801         if( real_cmap_size > 1024 )
00802         {
00803                 xpm_file->cmap = calloc( real_cmap_size, sizeof(ARGB32));
00804                 if( xpm_file->cmap == NULL ) /* we don't want to bomb out if image is busted */
00805                         real_cmap_size = 1024 ;
00806         }
00807         xpm_file->cmap = safecalloc( real_cmap_size, sizeof(ARGB32));
00808 #else
00809         if( xpm_file->bpp == 1 )
00810         {
00811                 real_cmap_size = 256 ;
00812                 xpm_file->cmap = safecalloc( real_cmap_size, sizeof(ARGB32));
00813         }else if( xpm_file->bpp == 2 )
00814         {
00815                 xpm_file->cmap2 = safecalloc( 256, sizeof(ARGB32*));
00816         }else
00817                 xpm_file->cmap_name_xref = create_ashash( 0, string_hash_value,
00818                                                                                                          string_compare,
00819                                                                                                          string_value_destroy );
00820 #endif
00821         if( xpm_color_names == NULL )
00822         {
00823                 xpm_color_names = create_ashash( 0, casestring_hash_value, casestring_compare, NULL );
00824                 for( i = 0 ; XpmRGB_Colors[i].name != NULL ; i++ )
00825                         add_hash_item( xpm_color_names, (ASHashableValue)XpmRGB_Colors[i].name, (void*)((long)XpmRGB_Colors[i].argb) );
00826         }
00827 
00828         for( i = 0 ; i < xpm_file->cmap_size ; ++i )
00829         {
00830                 ARGB32 color ;
00831 #ifdef HAVE_LIBXPM
00832                 if( i < real_cmap_size )
00833                 {
00834                         color = lookup_xpm_color((char**)&(xpm_cmap[i].string), xpm_color_names);
00835  LOCAL_DEBUG_OUT( "cmap[%d]: 0x%X\n",  i, color );
00836                         xpm_file->cmap[i] = color;
00837                         if( ARGB32_ALPHA8(color) != 0x00FF )
00838                         {       
00839                                 if( ARGB32_ALPHA8(color) != 0 ) 
00840                                         xpm_file->full_alpha = True ;
00841                                 xpm_file->do_alpha = True ;
00842                         }
00843                 }
00844 #else
00845                 char *colornames[6] ;
00846                 if( get_xpm_string( xpm_file ) != XPM_Success)
00847                         break;
00848 LOCAL_DEBUG_OUT( "cmap[%d]: \"%s\"\n",  i, xpm_file->str_buf );
00849                 if( !parse_xpm_cmap_entry( xpm_file, &(colornames[0])))
00850                         continue;
00851                 color = lookup_xpm_color(&(colornames[0]), xpm_color_names);
00852 LOCAL_DEBUG_OUT( "\t\tcolor = 0x%8.8lX\n",  color );
00853                 if( ARGB32_ALPHA8(color) != 0x00FF )
00854                         xpm_file->do_alpha = True ;
00855                 if( xpm_file->bpp == 1 )
00856                         xpm_file->cmap[(unsigned int)(xpm_file->str_buf[0])] = color ;
00857                 else if( xpm_file->bpp == 2 )
00858                 {
00859                         ARGB32 **slot = &(xpm_file->cmap2[(unsigned int)(xpm_file->str_buf[0])]) ;
00860                         if( *slot == NULL )
00861                                 *slot = safecalloc( 256, sizeof(ARGB32));
00862                         (*slot)[(unsigned int)(xpm_file->str_buf[1])] = color ;
00863                 }
00864                 else if( i < real_cmap_size )
00865                 {
00866                         char *name = mystrndup(xpm_file->str_buf, xpm_file->bpp);
00867 LOCAL_DEBUG_OUT( "\t\tname = \"%s\"\n", name );
00868                         add_hash_item( xpm_file->cmap_name_xref, (ASHashableValue)name, (void*)((long)color) );
00869                 }
00870 #endif
00871         }
00872         xpm_file->cmap_size = real_cmap_size ;
00873         return True;
00874 }
00875 
00876 Bool
00877 convert_xpm_scanline( ASXpmFile *xpm_file, unsigned int line )
00878 {
00879         CARD32 *r = xpm_file->scl.red, *g = xpm_file->scl.green,
00880                    *b = xpm_file->scl.blue,*a = (xpm_file->do_alpha)?xpm_file->scl.alpha:NULL ;
00881         register int k = xpm_file->width ;
00882         ARGB32 *cmap = xpm_file->cmap ;
00883 #ifdef HAVE_LIBXPM
00884         unsigned int *data = xpm_file->xpmImage.data+k*line ;
00885 #else
00886         unsigned char *data ;
00887         if( get_xpm_string( xpm_file ) != XPM_Success)
00888                 return False ;
00889         data = (unsigned char*)xpm_file->str_buf ;
00890 #endif
00891         if( cmap )
00892         {
00893                 while( --k >= 0 )
00894                         if( data[k] < xpm_file->cmap_size )
00895                         {
00896                                 register CARD32 c = cmap[data[k]] ;
00897                                 r[k] = ARGB32_RED8(c);
00898                                 g[k] = ARGB32_GREEN8(c);
00899                                 b[k] = ARGB32_BLUE8(c);
00900                                 if( a )
00901                                         a[k]  = ARGB32_ALPHA8(c);
00902                         }
00903         }else if( xpm_file->cmap2 )
00904         {
00905                 ARGB32 **cmap2 = xpm_file->cmap2 ;
00906                 while( --k >= 0 )
00907                 {
00908                         ARGB32 *slot = cmap2[data[k<<1]] ;
00909                         if( slot != NULL )
00910                         {
00911                                 register CARD32 c = slot[data[(k<<1)+1]] ;
00912                                 r[k] = ARGB32_RED8(c);
00913                                 g[k] = ARGB32_GREEN8(c);
00914                                 b[k] = ARGB32_BLUE8(c);
00915                                 if( a )
00916                                         a[k]  = ARGB32_ALPHA8(c);
00917                         }
00918                 }
00919         }else if( xpm_file->cmap_name_xref )
00920         {
00921                 char *pixel ;
00922                 pixel = safemalloc( xpm_file->bpp+1);
00923                 pixel[xpm_file->bpp] = '\0' ;
00924                 data += (k-1)*xpm_file->bpp ;
00925                 while( --k >= 0 )
00926                 {
00927                         register int i = xpm_file->bpp;
00928             ASHashData hdata = {0} ;
00929             CARD32 c = 0;
00930                         while( --i >= 0 )
00931                                 pixel[i] = data[i] ;
00932                         data -= xpm_file->bpp ;
00933             get_hash_item( xpm_file->cmap_name_xref, AS_HASHABLE(pixel), &hdata.vptr );
00934             /* on 64 bit system we must do that since pointers are 64 bit */
00935             c = hdata.c32;
00936                         r[k] = ARGB32_RED8(c);
00937                         g[k] = ARGB32_GREEN8(c);
00938                         b[k] = ARGB32_BLUE8(c);
00939                         if( a )
00940                                 a[k]  = ARGB32_ALPHA8(c);
00941                 }
00942                 free( pixel );
00943         }
00944         return True;
00945 }
00946 
00947 /**********************************************************************/
00948 /* XPM writing :                                                      */
00949 /**********************************************************************/
00950 
00951 ASXpmCharmap*
00952 build_xpm_charmap( ASColormap *cmap, Bool has_alpha, ASXpmCharmap *reusable_memory )
00953 {
00954         ASXpmCharmap *xpm_cmap = reusable_memory ;
00955         char *ptr ;
00956         int i ;
00957         int rem ;
00958 
00959         xpm_cmap->count = cmap->count+((has_alpha)?1:0) ;
00960 
00961         xpm_cmap->cpp = 0 ;
00962         for( rem = xpm_cmap->count ; rem > 0 ; rem = rem/MAXPRINTABLE )
00963                 ++(xpm_cmap->cpp) ;
00964         ptr = xpm_cmap->char_code = safemalloc(xpm_cmap->count*(xpm_cmap->cpp+1)) ;
00965         for( i = 0 ; i < (int)xpm_cmap->count ; i++ )
00966         {
00967                 register int k = xpm_cmap->cpp ;
00968                 rem = i ;
00969                 ptr[k] = '\0' ;
00970                 while( --k >= 0 )
00971                 {
00972                         ptr[k] = printable[rem%MAXPRINTABLE] ;
00973                         rem /= MAXPRINTABLE ;
00974                 }
00975                 ptr += xpm_cmap->cpp+1 ;
00976         }
00977 
00978         return xpm_cmap;
00979 }
00980 
00981 void destroy_xpm_charmap( ASXpmCharmap *xpm_cmap, Bool reusable )
00982 {
00983         if( xpm_cmap )
00984         {
00985                 if( xpm_cmap->char_code )
00986                         free( xpm_cmap->char_code );
00987                 if( !reusable )
00988                         free( xpm_cmap );
00989         }
00990 }
00991 
00992 #endif /* HAVE_XPM */

Generated on Tue Jul 5 14:13:33 2011 for ROOT_528-00b_version by  doxygen 1.5.1