00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
00080
00081
00082 static char *printable =
00083 " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
00084
00085 static struct {
00086 char *name ;
00087 ARGB32 argb ;
00088 } XpmRGB_Colors[] =
00089 {
00090
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
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
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
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' )
00483 key = 5;
00484 else
00485 {
00486 if( *ptr == 's' )
00487 key = 1;
00488 else if( *ptr == 'm' )
00489 key = 2;
00490 else if( *ptr == 'g' )
00491 key = 4;
00492 else
00493 key = 0;
00494 }
00495 }
00496 }
00497 }while( *ptr );
00498 return success;
00499 }
00500 #endif
00501
00502
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
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
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
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 )
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
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
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