/ fdf / fdf / mlx / mlx_xpm.c
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  }