mlx_xpm.c
1 // mlx xpm 2 // by ol 3 4 #include <stdlib.h> 5 #include <stdio.h> 6 #include <sys/mman.h> 7 #include <unistd.h> 8 #include <fcntl.h> 9 #include <string.h> 10 11 #include "mlx.h" 12 13 typedef struct s_xpm_col 14 { 15 int name; 16 int col; 17 } t_xpm_col; 18 19 20 struct s_col_name 21 { 22 char *name; 23 int color; 24 }; 25 26 //extern struct s_col_name mlx_col_name[]; 27 #include "mlx_rgb.c" 28 29 30 #define RETURN { if (colors) free(colors); if (tab) free(tab); \ 31 if (colors_direct) free(colors_direct); \ 32 if (img) mlx_destroy_image(xvar, img); \ 33 return ((void *)0); } 34 35 36 37 38 // 39 // str 2 wordtab & co 40 41 int mlx_int_str_str(char *str,char *find,int len) 42 { 43 int len_f; 44 int pos; 45 char *s; 46 char *f; 47 48 len_f = strlen(find); 49 if (len_f>len) 50 return (-1); 51 pos = 0; 52 while (*(str+len_f-1)) 53 { 54 s = str; 55 f = find; 56 while (*(f++) == *(s++)) 57 if (!*f) 58 return (pos); 59 str ++; 60 pos ++; 61 } 62 return (-1); 63 } 64 65 66 67 int mlx_int_str_str_cote(char *str,char *find,int len) 68 { 69 int len_f; 70 int pos; 71 char *s; 72 char *f; 73 int cote; 74 75 len_f = strlen(find); 76 if (len_f>len) 77 return (-1); 78 cote = 0; 79 pos = 0; 80 while (*(str+len_f-1)) 81 { 82 if (*str=='"') 83 cote = 1-cote; 84 if (!cote) 85 { 86 s = str; 87 f = find; 88 while (*(f++) == *(s++)) 89 if (!*f) 90 return (pos); 91 } 92 str ++; 93 pos ++; 94 } 95 return (-1); 96 } 97 98 99 char **mlx_int_str_to_wordtab(char *str) 100 { 101 char **tab; 102 int pos; 103 int nb_word; 104 int len; 105 106 len = strlen(str); 107 nb_word = 0; 108 pos = 0; 109 while (pos<len) 110 { 111 while (*(str+pos)==' ' || *(str+pos)=='\t') 112 pos ++; 113 if (*(str+pos)) 114 nb_word ++; 115 while (*(str+pos) && *(str+pos)!=' ' && *(str+pos)!='\t') 116 pos ++; 117 } 118 if (!(tab = malloc((1+nb_word)*sizeof(*tab)))) 119 return ((char **)0); 120 nb_word = 0; 121 pos = 0; 122 while (pos<len) 123 { 124 while (*(str+pos)==' ' || *(str+pos)=='\t') 125 { 126 *(str+pos) = 0; 127 pos ++; 128 } 129 if (*(str+pos)) 130 { 131 tab[nb_word] = str+pos; 132 nb_word ++; 133 } 134 while (*(str+pos) && *(str+pos)!=' ' && *(str+pos)!='\t') 135 pos ++; 136 } 137 tab[nb_word] = 0; 138 return (tab); 139 } 140 141 142 // back to mlx_xpm 143 144 145 146 char *mlx_int_get_line(char *ptr,int *pos,int size) 147 { 148 int pos2; 149 int pos3; 150 int pos4; 151 152 if ((pos2 = mlx_int_str_str(ptr+*pos,"\"",size-*pos))==-1) 153 return ((char *)0); 154 if ((pos3 = mlx_int_str_str(ptr+*pos+pos2+1,"\"",size-*pos-pos2-1))==-1) 155 return ((char *)0); 156 *(ptr+*pos+pos2) = 0; 157 *(ptr+*pos+pos2+1+pos3) = 0; 158 pos4 = *pos+pos2+1; 159 *pos += pos2+pos3+2; 160 return (ptr+pos4); 161 } 162 163 164 165 char *mlx_int_static_line(char **xpm_data,int *pos,int size) 166 { 167 static char *copy = 0; 168 static int len = 0; 169 int len2; 170 char *str; 171 172 str = xpm_data[(*pos)++]; 173 if ((len2 = strlen(str))>len) 174 { 175 if (copy) 176 free(copy); 177 if (!(copy = malloc(len2+1))) 178 return ((char *)0); 179 len = len2; 180 } 181 /* strcpy(copy,str); */ 182 strlcpy(copy, str, len2+1); 183 return (copy); 184 } 185 186 187 int mlx_int_get_col_name(char *str,int size) 188 { 189 int result; 190 191 result = 0; 192 while (size--) 193 result = (result<<8)+*(str++); 194 return (result); 195 } 196 197 int mlx_int_get_text_rgb(char *name, char *end) 198 { 199 int i; 200 char buff[64]; 201 202 if (*name == '#') 203 return (strtol(name+1,0,16)); 204 if (end) 205 { 206 snprintf(buff, 64, "%s %s", name, end); 207 name = buff; 208 } 209 i = 0; 210 while (mlx_col_name[i].name) 211 { 212 if (!strcasecmp(mlx_col_name[i].name, name)) 213 return (mlx_col_name[i].color); 214 i ++; 215 } 216 return (0); 217 } 218 219 220 void mlx_int_xpm_set_pixel(char *data, int opp, int col, int x) 221 { 222 *((unsigned int *)(data+4*x)) = col; 223 } 224 225 226 void *mlx_int_parse_xpm(void *xvar,void *info,int info_size,char *(*f)(), int *width, int *height) 227 { 228 int pos; 229 char *line; 230 char **tab; 231 char *data; 232 char *clip_data; 233 int nc; 234 int opp; 235 int sl; 236 int endian; 237 int cpp; 238 int col; 239 int rgb_col; 240 int col_name; 241 int method; 242 int x; 243 int i; 244 int j; 245 void *img; 246 t_xpm_col *colors; 247 int *colors_direct; 248 249 colors = 0; 250 colors_direct = 0; 251 img = 0; 252 tab = 0; 253 pos = 0; 254 if (!(line = f(info,&pos,info_size)) || 255 !(tab = mlx_int_str_to_wordtab(line)) || !(*width = atoi(tab[0])) || 256 !(*height = atoi(tab[1])) || !(nc = atoi(tab[2])) || 257 !(cpp = atoi(tab[3])) ) 258 RETURN; 259 free(tab); 260 tab = 0; 261 262 method = 0; 263 if (cpp<=2) 264 { 265 method = 1; 266 if (!(colors_direct = malloc((cpp==2?65536:256)*sizeof(int)))) 267 RETURN; 268 } 269 else 270 if (!(colors = malloc(nc*sizeof(*colors)))) 271 RETURN; 272 273 clip_data = 0; 274 275 i = nc; 276 while (i--) 277 { 278 if (!(line = f(info,&pos,info_size)) || 279 !(tab = mlx_int_str_to_wordtab(line+cpp)) ) 280 RETURN; 281 j = 0; 282 while (tab[j] && strcmp(tab[j++],"c")); 283 284 if (!tab[j]) 285 RETURN; 286 287 rgb_col = mlx_int_get_text_rgb(tab[j], tab[j+1]); 288 if (method) 289 colors_direct[mlx_int_get_col_name(line,cpp)] = rgb_col; 290 else 291 { 292 colors[i].name = mlx_int_get_col_name(line,cpp); 293 colors[i].col = rgb_col; 294 } 295 free(tab); 296 tab = 0; 297 } 298 299 if (!(img = mlx_new_image(xvar,*width,*height))) 300 RETURN; 301 data = mlx_get_data_addr(img, &opp, &sl, &endian); 302 opp = 4; 303 304 i = *height; 305 while (i--) 306 { 307 if (!(line = f(info,&pos,info_size))) 308 RETURN; 309 x = 0; 310 while (x<*width) 311 { 312 col = 0; 313 col_name = mlx_int_get_col_name(line+cpp*x,cpp); 314 if (method) 315 col = colors_direct[col_name]; 316 else 317 { 318 j = nc; 319 while (j--) 320 if (colors[j].name==col_name) 321 { 322 col = colors[j].col; 323 j = 0; 324 } 325 } 326 if (col==-1) 327 col = 0xFF000000; 328 mlx_int_xpm_set_pixel(data, opp, col, x); 329 x ++; 330 } 331 data += sl; //img->width*4; 332 } 333 if (colors) 334 free(colors); 335 if (colors_direct) 336 free(colors_direct); 337 return (img); 338 } 339 340 341 void mlx_int_file_get_rid_comment(char *ptr, int size) 342 { 343 int com_begin; 344 int com_end; 345 346 while ((com_begin = mlx_int_str_str_cote(ptr,"/*",size))!=-1) 347 { 348 com_end = mlx_int_str_str(ptr+com_begin+2,"*/",size-com_begin-2); 349 memset(ptr+com_begin,' ',com_end+4); 350 } 351 while ((com_begin = mlx_int_str_str_cote(ptr,"//",size))!=-1) 352 { 353 com_end = mlx_int_str_str(ptr+com_begin+2,"\n",size-com_begin-2); 354 memset(ptr+com_begin,' ',com_end+3); 355 } 356 } 357 358 359 void *mlx_xpm_file_to_image(void *xvar,char *file,int *width,int *height) 360 { 361 int fd; 362 int size; 363 char *ptr; 364 void *img; 365 366 if ((fd = open(file,O_RDONLY))==-1 || (size = lseek(fd,0,SEEK_END))==-1 || 367 (ptr = mmap(0,size,PROT_WRITE|PROT_READ,MAP_PRIVATE,fd,0))== 368 (void *)MAP_FAILED) 369 { 370 if (fd>=0) 371 close(fd); 372 return ((void *)0); 373 } 374 mlx_int_file_get_rid_comment(ptr, size); 375 img = mlx_int_parse_xpm(xvar,ptr,size,mlx_int_get_line, width, height); 376 munmap(ptr,size); 377 close(fd); 378 return (img); 379 } 380 381 void *mlx_xpm_to_image(void *xvar,char **xpm_data,int *width,int *height) 382 { 383 return (mlx_int_parse_xpm(xvar,xpm_data,0,mlx_int_static_line, width, height)); 384 }