diff options
Diffstat (limited to 'minilibx_beta/mlx_xpm.c')
-rw-r--r-- | minilibx_beta/mlx_xpm.c | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/minilibx_beta/mlx_xpm.c b/minilibx_beta/mlx_xpm.c new file mode 100644 index 0000000..25fdafe --- /dev/null +++ b/minilibx_beta/mlx_xpm.c @@ -0,0 +1,384 @@ +// mlx xpm +// by ol + +#include <stdlib.h> +#include <stdio.h> +#include <sys/mman.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> + +#include "mlx.h" + +typedef struct s_xpm_col +{ + int name; + int col; +} t_xpm_col; + + +struct s_col_name +{ + char *name; + int color; +}; + +//extern struct s_col_name mlx_col_name[]; +#include "mlx_rgb.c" + + +#define RETURN { if (colors) free(colors); if (tab) free(tab); \ + if (colors_direct) free(colors_direct); \ + if (img) mlx_destroy_image(xvar, img); \ + return ((void *)0); } + + + + +// +// str 2 wordtab & co + +int mlx_int_str_str(char *str,char *find,int len) +{ + int len_f; + int pos; + char *s; + char *f; + + len_f = strlen(find); + if (len_f>len) + return (-1); + pos = 0; + while (*(str+len_f-1)) + { + s = str; + f = find; + while (*(f++) == *(s++)) + if (!*f) + return (pos); + str ++; + pos ++; + } + return (-1); +} + + + +int mlx_int_str_str_cote(char *str,char *find,int len) +{ + int len_f; + int pos; + char *s; + char *f; + int cote; + + len_f = strlen(find); + if (len_f>len) + return (-1); + cote = 0; + pos = 0; + while (*(str+len_f-1)) + { + if (*str=='"') + cote = 1-cote; + if (!cote) + { + s = str; + f = find; + while (*(f++) == *(s++)) + if (!*f) + return (pos); + } + str ++; + pos ++; + } + return (-1); +} + + +char **mlx_int_str_to_wordtab(char *str) +{ + char **tab; + int pos; + int nb_word; + int len; + + len = strlen(str); + nb_word = 0; + pos = 0; + while (pos<len) + { + while (*(str+pos)==' ' || *(str+pos)=='\t') + pos ++; + if (*(str+pos)) + nb_word ++; + while (*(str+pos) && *(str+pos)!=' ' && *(str+pos)!='\t') + pos ++; + } + if (!(tab = malloc((1+nb_word)*sizeof(*tab)))) + return ((char **)0); + nb_word = 0; + pos = 0; + while (pos<len) + { + while (*(str+pos)==' ' || *(str+pos)=='\t') + { + *(str+pos) = 0; + pos ++; + } + if (*(str+pos)) + { + tab[nb_word] = str+pos; + nb_word ++; + } + while (*(str+pos) && *(str+pos)!=' ' && *(str+pos)!='\t') + pos ++; + } + tab[nb_word] = 0; + return (tab); +} + + +// back to mlx_xpm + + + +char *mlx_int_get_line(char *ptr,int *pos,int size) +{ + int pos2; + int pos3; + int pos4; + + if ((pos2 = mlx_int_str_str(ptr+*pos,"\"",size-*pos))==-1) + return ((char *)0); + if ((pos3 = mlx_int_str_str(ptr+*pos+pos2+1,"\"",size-*pos-pos2-1))==-1) + return ((char *)0); + *(ptr+*pos+pos2) = 0; + *(ptr+*pos+pos2+1+pos3) = 0; + pos4 = *pos+pos2+1; + *pos += pos2+pos3+2; + return (ptr+pos4); +} + + + +char *mlx_int_static_line(char **xpm_data,int *pos,int size) +{ + static char *copy = 0; + static int len = 0; + int len2; + char *str; + + str = xpm_data[(*pos)++]; + if ((len2 = strlen(str))>len) + { + if (copy) + free(copy); + if (!(copy = malloc(len2+1))) + return ((char *)0); + len = len2; + } + /* strcpy(copy,str); */ + strlcpy(copy, str, len2+1); + return (copy); +} + + +int mlx_int_get_col_name(char *str,int size) +{ + int result; + + result = 0; + while (size--) + result = (result<<8)+*(str++); + return (result); +} + +int mlx_int_get_text_rgb(char *name, char *end) +{ + int i; + char buff[64]; + + if (*name == '#') + return (strtol(name+1,0,16)); + if (end) + { + snprintf(buff, 64, "%s %s", name, end); + name = buff; + } + i = 0; + while (mlx_col_name[i].name) + { + if (!strcasecmp(mlx_col_name[i].name, name)) + return (mlx_col_name[i].color); + i ++; + } + return (0); +} + + +void mlx_int_xpm_set_pixel(char *data, int opp, int col, int x) +{ + *((unsigned int *)(data+4*x)) = col; +} + + +void *mlx_int_parse_xpm(void *xvar,void *info,int info_size,char *(*f)(), int *width, int *height) +{ + int pos; + char *line; + char **tab; + char *data; + char *clip_data; + int nc; + int opp; + int sl; + int endian; + int cpp; + int col; + int rgb_col; + int col_name; + int method; + int x; + int i; + int j; + void *img; + t_xpm_col *colors; + int *colors_direct; + + colors = 0; + colors_direct = 0; + img = 0; + tab = 0; + pos = 0; + if (!(line = f(info,&pos,info_size)) || + !(tab = mlx_int_str_to_wordtab(line)) || !(*width = atoi(tab[0])) || + !(*height = atoi(tab[1])) || !(nc = atoi(tab[2])) || + !(cpp = atoi(tab[3])) ) + RETURN; + free(tab); + tab = 0; + + method = 0; + if (cpp<=2) + { + method = 1; + if (!(colors_direct = malloc((cpp==2?65536:256)*sizeof(int)))) + RETURN; + } + else + if (!(colors = malloc(nc*sizeof(*colors)))) + RETURN; + + clip_data = 0; + + i = nc; + while (i--) + { + if (!(line = f(info,&pos,info_size)) || + !(tab = mlx_int_str_to_wordtab(line+cpp)) ) + RETURN; + j = 0; + while (tab[j] && strcmp(tab[j++],"c")); + + if (!tab[j]) + RETURN; + + rgb_col = mlx_int_get_text_rgb(tab[j], tab[j+1]); + if (method) + colors_direct[mlx_int_get_col_name(line,cpp)] = rgb_col; + else + { + colors[i].name = mlx_int_get_col_name(line,cpp); + colors[i].col = rgb_col; + } + free(tab); + tab = 0; + } + + if (!(img = mlx_new_image(xvar,*width,*height))) + RETURN; + data = mlx_get_data_addr(img, &opp, &sl, &endian); + opp = 4; + + i = *height; + while (i--) + { + if (!(line = f(info,&pos,info_size))) + RETURN; + x = 0; + while (x<*width) + { + col = 0; + col_name = mlx_int_get_col_name(line+cpp*x,cpp); + if (method) + col = colors_direct[col_name]; + else + { + j = nc; + while (j--) + if (colors[j].name==col_name) + { + col = colors[j].col; + j = 0; + } + } + if (col==-1) + col = 0xFF000000; + mlx_int_xpm_set_pixel(data, opp, col, x); + x ++; + } + data += sl; //img->width*4; + } + if (colors) + free(colors); + if (colors_direct) + free(colors_direct); + return (img); +} + + +void mlx_int_file_get_rid_comment(char *ptr, int size) +{ + int com_begin; + int com_end; + + while ((com_begin = mlx_int_str_str_cote(ptr,"/*",size))!=-1) + { + com_end = mlx_int_str_str(ptr+com_begin+2,"*/",size-com_begin-2); + memset(ptr+com_begin,' ',com_end+4); + } + while ((com_begin = mlx_int_str_str_cote(ptr,"//",size))!=-1) + { + com_end = mlx_int_str_str(ptr+com_begin+2,"\n",size-com_begin-2); + memset(ptr+com_begin,' ',com_end+3); + } +} + + +void *mlx_xpm_file_to_image(void *xvar,char *file,int *width,int *height) +{ + int fd; + int size; + char *ptr; + void *img; + + if ((fd = open(file,O_RDONLY))==-1 || (size = lseek(fd,0,SEEK_END))==-1 || + (ptr = mmap(0,size,PROT_WRITE|PROT_READ,MAP_PRIVATE,fd,0))== + (void *)MAP_FAILED) + { + if (fd>=0) + close(fd); + return ((void *)0); + } + mlx_int_file_get_rid_comment(ptr, size); + img = mlx_int_parse_xpm(xvar,ptr,size,mlx_int_get_line, width, height); + munmap(ptr,size); + close(fd); + return (img); +} + +void *mlx_xpm_to_image(void *xvar,char **xpm_data,int *width,int *height) +{ + return (mlx_int_parse_xpm(xvar,xpm_data,0,mlx_int_static_line, width, height)); +} |