diff options
author | Rudy Bousset <rbousset@z2r4p3.le-101.fr> | 2020-02-09 14:31:57 +0100 |
---|---|---|
committer | Rudy Bousset <rbousset@z2r4p3.le-101.fr> | 2020-02-09 14:31:57 +0100 |
commit | 4fa8a129e6ecfa168604568673cfbdaa2c8e34b0 (patch) | |
tree | 6e97965f1a32c007533eadb15becb4b9405867ea /minilibx/mlx_xpm.c | |
parent | Reverted map to normal size (diff) | |
download | 42-cub3d-4fa8a129e6ecfa168604568673cfbdaa2c8e34b0.tar.gz 42-cub3d-4fa8a129e6ecfa168604568673cfbdaa2c8e34b0.tar.bz2 42-cub3d-4fa8a129e6ecfa168604568673cfbdaa2c8e34b0.tar.xz 42-cub3d-4fa8a129e6ecfa168604568673cfbdaa2c8e34b0.tar.zst 42-cub3d-4fa8a129e6ecfa168604568673cfbdaa2c8e34b0.zip |
Renamed minilibx
Diffstat (limited to 'minilibx/mlx_xpm.c')
-rw-r--r-- | minilibx/mlx_xpm.c | 338 |
1 files changed, 338 insertions, 0 deletions
diff --git a/minilibx/mlx_xpm.c b/minilibx/mlx_xpm.c new file mode 100644 index 0000000..78d8c9b --- /dev/null +++ b/minilibx/mlx_xpm.c @@ -0,0 +1,338 @@ +// mlx xpm +// by ol + +#include <OpenGL/gl3.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/mman.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include "mlx_int.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); } + + + + +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(mlx_img_list_t *img, char *data, int opp, int col, int x) +{ + /* + int dec; + + dec = opp; + while (dec--) + { + if (img->image->byte_order) + *(data+x*opp+dec) = col&0xFF; + else + *(data+x*opp+opp-dec-1) = col&0xFF; + col >>= 8; + } + */ + // opp is 4, do it the simple way + *((unsigned int *)(data+4*x)) = col; +} + + +void *mlx_int_parse_xpm(mlx_ptr_t *xvar,void *info,int info_size,char *(*f)()) +{ + int pos; + char *line; + char **tab; + char *data; + char *clip_data; + int nc; + int opp; + int cpp; + int col; + int rgb_col; + int col_name; + int method; + int x; + int i; + int j; + mlx_img_list_t *img; + t_xpm_col *colors; + int *colors_direct; + int width; + int height; + + 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 ((rgb_col = mlx_int_get_text_rgb(tab[j], tab[j+1]))==-1) + { + if (!(clip_data = malloc(4*width*height)) || // ok, nice size .. + !(clip_img = XCreateImage(xvar->display, xvar->visual, + 1, XYPixmap, 0, clip_data, + width, height, 8, (width+7)/8)) ) + RETURN; + memset(clip_data, 0xFF, 4*width*height); + } + */ + if (method) + colors_direct[mlx_int_get_col_name(line,cpp)] = rgb_col; + // rgb_col>=0?mlx_get_color_value(xvar, rgb_col):rgb_col; + else + { + colors[i].name = mlx_int_get_col_name(line,cpp); + colors[i].col = rgb_col; // rgb_col>=0?mlx_get_color_value(xvar,rgb_col):rgb_col; + } + free(tab); + tab = 0; + } + + if (!(img = mlx_new_image(xvar,width,height))) + RETURN; + //opp = img->bpp/8; + opp = 4; + + + i = height; + data = img->buffer; + 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) + // XPutPixel(clip_img, x, height-1-i, 0); + // else + if (col==-1) + col = 0xFF000000; + mlx_int_xpm_set_pixel(img, data, opp, col, x); + x ++; + } + // data += img->size_line; + data += img->width*4; + } + /* + if (clip_data) + { + if (!(clip_pix = XCreatePixmap(xvar->display, xvar->root, + width, height, 1)) ) + RETURN; + img->gc = XCreateGC(xvar->display, clip_pix, 0, &xgcv); + XPutImage(xvar->display, clip_pix, img->gc, clip_img, + 0, 0, 0, 0, width, height); + XFreeGC(xvar->display, img->gc); + xgcv.clip_mask = clip_pix; + xgcv.function = GXcopy; + xgcv.plane_mask = AllPlanes; + img->gc = XCreateGC(xvar->display, xvar->root, GCClipMask|GCFunction| + GCPlaneMask, &xgcv); + XSync(xvar->display, False); + XDestroyImage(clip_img); + } + */ + 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(mlx_ptr_t *xvar,char *file,int *width,int *height) +{ + int fd; + int size; + char *ptr; + mlx_img_list_t *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); + if ((img = mlx_int_parse_xpm(xvar,ptr,size,mlx_int_get_line))) + { + *width = img->width; + *height = img->height; + } + munmap(ptr,size); + close(fd); + return (img); +} + +void *mlx_xpm_to_image(mlx_ptr_t *xvar,char **xpm_data,int *width,int *height) +{ + mlx_img_list_t *img; + + if ((img = mlx_int_parse_xpm(xvar,xpm_data,0,mlx_int_static_line))) + { + *width = img->width; + *height = img->height; + } + return (img); +} |