/ minilibx-linux / mlx_xpm.c
mlx_xpm.c
1 /* 2 ** xpm-read.c for MinilibX in 3 ** 4 ** Made by Charlie Root 5 ** Login <ol@epitech.net> 6 ** 7 ** Started on Tue Dec 11 15:25:27 2001 olivier crouzet 8 ** Last update Sat Oct 1 14:56:13 2005 Olivier Crouzet 9 */ 10 11 12 #include "mlx_int.h" 13 14 extern struct s_col_name mlx_col_name[]; 15 16 17 #define RETURN { if (colors) free(colors); if (tab) free(tab); \ 18 tab = (void *)0; if (colors_direct) free(colors_direct); \ 19 if (img) {XDestroyImage(img->image); \ 20 XFreePixmap(xvar->display,img->pix);free(img);} \ 21 return ((void *)0);} 22 23 24 25 26 char *mlx_int_get_line(char *ptr,int *pos,int size) 27 { 28 int pos2; 29 int pos3; 30 int pos4; 31 32 if ((pos2 = mlx_int_str_str(ptr+*pos,"\"",size-*pos))==-1) 33 return ((char *)0); 34 if ((pos3 = mlx_int_str_str(ptr+*pos+pos2+1,"\"",size-*pos-pos2-1))==-1) 35 return ((char *)0); 36 *(ptr+*pos+pos2) = 0; 37 *(ptr+*pos+pos2+1+pos3) = 0; 38 pos4 = *pos+pos2+1; 39 *pos += pos2+pos3+2; 40 return (ptr+pos4); 41 } 42 43 44 unsigned int strlcpy_is_not_posix(char *dest, char *src, unsigned int size) 45 { 46 unsigned count; 47 unsigned i; 48 49 count = 0; 50 while (src[count] != '\0') 51 ++count; 52 i = 0; 53 while (src[i] != '\0' && i < (size - 1)) 54 { 55 dest[i] = src[i]; 56 ++i; 57 } 58 dest[i] = '\0'; 59 return (count); 60 } 61 62 char *mlx_int_static_line(char **xpm_data,int *pos,int size) 63 { 64 static char *copy = 0; 65 static int len = 0; 66 int len2; 67 char *str; 68 69 str = xpm_data[(*pos)++]; 70 if ((len2 = strlen(str))>len) 71 { 72 if (copy) 73 free(copy); 74 if (!(copy = malloc(len2+1))) 75 return ((char *)0); 76 len = len2; 77 } 78 strlcpy_is_not_posix(copy, str, len2); 79 80 return (copy); 81 } 82 83 84 int mlx_int_get_col_name(char *str,int size) 85 { 86 int result; 87 88 result = 0; 89 while (size--) 90 result = (result<<8)+*(str++); 91 92 return (result); 93 } 94 95 int mlx_int_get_text_rgb(char *name, char *end) 96 { 97 int i; 98 char buff[64]; 99 100 if (*name == '#') 101 return (strtol(name+1,0,16)); 102 if (end) 103 { 104 snprintf(buff, 64, "%s %s", name, end); 105 name = buff; 106 } 107 i = 0; 108 while (mlx_col_name[i].name) 109 { 110 if (!strcasecmp(mlx_col_name[i].name, name)) 111 return (mlx_col_name[i].color); 112 i ++; 113 } 114 return (0); 115 } 116 117 118 int mlx_int_xpm_set_pixel(t_img *img, char *data, int opp, int col, int x) 119 { 120 int dec; 121 122 dec = opp; 123 while (dec--) 124 { 125 if (img->image->byte_order) 126 *(data+x*opp+dec) = col&0xFF; 127 else 128 *(data+x*opp+opp-dec-1) = col&0xFF; 129 col >>= 8; 130 } 131 } 132 133 134 void *mlx_int_parse_xpm(t_xvar *xvar,void *info,int info_size,char *(*f)()) 135 { 136 int pos; 137 char *line; 138 char **tab; 139 char *data; 140 char *clip_data; 141 int nc; 142 int opp; 143 int cpp; 144 int col; 145 int rgb_col; 146 int col_name; 147 int method; 148 int x; 149 int i; 150 int j; 151 t_img *img; 152 t_xpm_col *colors; 153 int *colors_direct; 154 int width; 155 int height; 156 XImage *clip_img; 157 XGCValues xgcv; 158 Pixmap clip_pix; 159 160 colors = 0; 161 colors_direct = 0; 162 img = 0; 163 tab = 0; 164 pos = 0; 165 if (!(line = f(info,&pos,info_size)) || 166 !(tab = mlx_int_str_to_wordtab(line)) || !(width = atoi(tab[0])) || 167 !(height = atoi(tab[1])) || !(nc = atoi(tab[2])) || 168 !(cpp = atoi(tab[3])) ) 169 RETURN; 170 free(tab); 171 tab = 0; 172 173 method = 0; 174 if (cpp<=2) 175 { 176 method = 1; 177 if (!(colors_direct = malloc((cpp==2?65536:256)*sizeof(int)))) 178 RETURN; 179 } 180 else 181 if (!(colors = malloc(nc*sizeof(*colors)))) 182 RETURN; 183 184 clip_data = 0; 185 186 i = nc; 187 while (i--) 188 { 189 if (!(line = f(info,&pos,info_size)) || 190 !(tab = mlx_int_str_to_wordtab(line+cpp)) ) 191 RETURN; 192 j = 0; 193 while (tab[j] && strcmp(tab[j++],"c")); 194 195 if (!tab[j]) 196 RETURN; 197 rgb_col = mlx_int_get_text_rgb(tab[j], tab[j+1]); 198 /* 199 if ((rgb_col = mlx_int_get_text_rgb(tab[j], tab[j+1]))==-1) 200 { 201 if (!(clip_data = malloc(4*width*height)) || ok, nice size .. 202 !(clip_img = XCreateImage(xvar->display, xvar->visual, 203 1, XYPixmap, 0, clip_data, 204 width, height, 8, (width+7)/8)) ) 205 RETURN; 206 memset(clip_data, 0xFF, 4*width*height); 207 } 208 */ 209 if (method) 210 colors_direct[mlx_int_get_col_name(line,cpp)] = rgb_col; 211 // rgb_col>=0?mlx_get_color_value(xvar, rgb_col):rgb_col; 212 else 213 { 214 colors[i].name = mlx_int_get_col_name(line,cpp); 215 colors[i].col = rgb_col; //rgb_col>=0?mlx_get_color_value(xvar,rgb_col):rgb_col; 216 } 217 free(tab); 218 tab = (void *)0; 219 } 220 221 if (!(img = mlx_new_image(xvar,width,height))) 222 RETURN; 223 opp = img->bpp/8; 224 225 226 i = height; 227 data = img->data; 228 while (i--) 229 { 230 if (!(line = f(info,&pos,info_size))) 231 RETURN; 232 x = 0; 233 while (x<width) 234 { 235 col = 0; 236 col_name = mlx_int_get_col_name(line+cpp*x,cpp); 237 if (method) 238 col = colors_direct[col_name]; 239 else 240 { 241 j = nc; 242 while (j--) 243 if (colors[j].name==col_name) 244 { 245 col = colors[j].col; 246 j = 0; 247 } 248 } 249 /* 250 if (col==-1) 251 XPutPixel(clip_img, x, height-1-i, 0); 252 else 253 mlx_int_xpm_set_pixel(img, data, opp, col, x); 254 x ++; 255 */ 256 if (col==-1) 257 col = 0xFF000000; 258 mlx_int_xpm_set_pixel(img, data, opp, col, x); 259 ++x; 260 } 261 data += img->size_line; 262 } 263 /* 264 if (clip_data) 265 { 266 if (!(clip_pix = XCreatePixmap(xvar->display, xvar->root, 267 width, height, 1)) ) 268 RETURN; 269 img->gc = XCreateGC(xvar->display, clip_pix, 0, &xgcv); 270 XPutImage(xvar->display, clip_pix, img->gc, clip_img, 271 0, 0, 0, 0, width, height); 272 XFreeGC(xvar->display, img->gc); 273 xgcv.clip_mask = clip_pix; 274 xgcv.function = GXcopy; 275 xgcv.plane_mask = AllPlanes; 276 img->gc = XCreateGC(xvar->display, xvar->root, GCClipMask|GCFunction| 277 GCPlaneMask, &xgcv); 278 XSync(xvar->display, False); 279 XDestroyImage(clip_img); 280 } 281 */ 282 if (colors) 283 free(colors); 284 if (colors_direct) 285 free(colors_direct); 286 return (img); 287 } 288 289 290 int mlx_int_file_get_rid_comment(char *ptr, int size) 291 { 292 int com_begin; 293 int com_end; 294 295 while ((com_begin = mlx_int_str_str_cote(ptr,"/*",size))!=-1) 296 { 297 com_end = mlx_int_str_str(ptr+com_begin+2,"*/",size-com_begin-2); 298 memset(ptr+com_begin,' ',com_end+4); 299 } 300 while ((com_begin = mlx_int_str_str_cote(ptr,"//",size))!=-1) 301 { 302 com_end = mlx_int_str_str(ptr+com_begin+2,"\n",size-com_begin-2); 303 memset(ptr+com_begin,' ',com_end+3); 304 } 305 } 306 307 308 void *mlx_xpm_file_to_image(t_xvar *xvar,char *file,int *width,int *height) 309 { 310 int fd; 311 int size; 312 char *ptr; 313 t_img *img; 314 315 fd = -1; 316 if ((fd = open(file,O_RDONLY))==-1 || (size = lseek(fd,0,SEEK_END))==-1 || 317 (ptr = mmap(0,size,PROT_WRITE|PROT_READ,MAP_PRIVATE,fd,0))== 318 (void *)MAP_FAILED) 319 { 320 if (fd>=0) 321 close(fd); 322 return ((void *)0); 323 } 324 mlx_int_file_get_rid_comment(ptr, size); 325 if (img = mlx_int_parse_xpm(xvar,ptr,size,mlx_int_get_line)) 326 { 327 *width = img->width; 328 *height = img->height; 329 } 330 munmap(ptr,size); 331 close(fd); 332 return (img); 333 } 334 335 void *mlx_xpm_to_image(t_xvar *xvar,char **xpm_data,int *width,int *height) 336 { 337 t_img *img; 338 339 if (img = mlx_int_parse_xpm(xvar,xpm_data,0,mlx_int_static_line)) 340 { 341 *width = img->width; 342 *height = img->height; 343 } 344 return (img); 345 }