/ 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  }