From e9e9684117719204929821028ba9dbb7915ea119 Mon Sep 17 00:00:00 2001 From: kraxel Date: Sun, 28 Mar 2004 11:31:57 +0000 Subject: Initial revision --- rd/read-xpm.c | 287 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 rd/read-xpm.c (limited to 'rd/read-xpm.c') diff --git a/rd/read-xpm.c b/rd/read-xpm.c new file mode 100644 index 0000000..affdce6 --- /dev/null +++ b/rd/read-xpm.c @@ -0,0 +1,287 @@ +#include +#include +#include +#include + +#include +#include + +#include "ida.h" + +#include "readers.h" +#include "viewer.h" + +/* ---------------------------------------------------------------------- */ +/* load */ + +struct xpm_color { + char name[8]; + XColor color; +}; + +struct xpm_state { + FILE *infile; + int width,height,colors,chars; + struct xpm_color *cmap; + char *charline; + char *rgbrow; +}; + +static void* +xpm_init(FILE *fp, char *filename, unsigned int page, + struct ida_image_info *info, int thumbnail) +{ + struct xpm_state *h; + char line[1024],cname[32],*tmp; + XColor dummy; + int i; + Colormap cmap = DefaultColormapOfScreen(XtScreen(app_shell)); + + h = malloc(sizeof(*h)); + memset(h,0,sizeof(*h)); + h->infile = fp; + + fgets(line,sizeof(line)-1,fp); /* XPM */ + fgets(line,sizeof(line)-1,fp); /* static char ... */ + while (0 == strncmp(line,"/*",2)) { + while (NULL == strstr(line,"*/")) + fgets(line,sizeof(line)-1,fp); + fgets(line,sizeof(line)-1,fp); + } + + /* size, colors */ + fgets(line,sizeof(line)-1,fp); + if (0 == strncmp(line,"/*",2)) { + while (NULL == strstr(line,"*/")) + fgets(line,sizeof(line)-1,fp); + fgets(line,sizeof(line)-1,fp); + } + if (4 != sscanf(line,"\"%d %d %d %d", + &h->width,&h->height,&h->colors,&h->chars)) + goto oops; + if (h->chars > 7) + goto oops; + + /* read color table */ + h->cmap = malloc(h->colors * sizeof(struct xpm_color)); + memset(h->cmap,0,h->colors * sizeof(struct xpm_color)); + for (i = 0; i < h->colors; i++) { + fgets(line,sizeof(line)-1,fp); + while (0 == strncmp(line,"/*",2)) { + while (NULL == strstr(line,"*/")) + fgets(line,sizeof(line)-1,fp); + fgets(line,sizeof(line)-1,fp); + } + memcpy(h->cmap[i].name,line+1,h->chars); + + if (NULL != (tmp = strstr(line+1+h->chars,"c "))) { + /* color */ + sscanf(tmp+2,"%32[^\" ]",cname); + } else if (NULL != (tmp = strstr(line+h->chars,"m "))) { + /* mono */ + sscanf(tmp+2,"%32[^\" ]",cname); + } else if (NULL != (tmp = strstr(line+h->chars,"g "))) { + /* gray? */ + sscanf(tmp+2,"%32[^\" ]",cname); + } else + goto oops; + if (0 == strcasecmp(cname,"none")) + /* transparent */ + strcpy(cname,"lightgray"); + if (debug) + fprintf(stderr,"xpm: cmap: \"%*.*s\" => %s\n", + h->chars,h->chars,h->cmap[i].name,cname); +#if 0 + if (1 != sscanf(line+1+h->chars," c %32[^\"]",cname)) + goto oops; +#endif + XLookupColor(dpy,cmap,cname,&h->cmap[i].color,&dummy); + } + h->charline = malloc(h->width * h->chars + 8); + h->rgbrow = malloc(h->width * 3); + + info->width = h->width; + info->height = h->height; + info->npages = 1; + return h; + + oops: + fclose(fp); + free(h); + return NULL; +} + +static void +xpm_read(unsigned char *dst, unsigned int line, void *data) +{ + struct xpm_state *h = data; + char *src; + int i,c; + + fgets(h->charline,h->width * h->chars + 8,h->infile); + while (0 == strncmp(h->charline,"/*",2)) { + while (NULL == strstr(h->charline,"*/")) + fgets(h->charline,h->width * h->chars + 8,h->infile); + fgets(h->charline,h->width * h->chars + 8,h->infile); + } + src = h->charline+1; + for (i = 0; i < h->width; i++) { + for (c = 0; c < h->colors; c++) { + char *name = h->cmap[c].name; + if (src[0] != name[0]) + continue; + if (1 == h->chars) + break; + if (src[1] != name[1]) + continue; + if (2 == h->chars) + break; + if (0 == strncmp(src+2,name+2,h->chars-2)) + break; + } + if (c == h->colors) + continue; + dst[0] = h->cmap[c].color.red >> 8; + dst[1] = h->cmap[c].color.green >> 8; + dst[2] = h->cmap[c].color.blue >> 8; + src += h->chars; + dst += 3; + } +} + +static void +xpm_done(void *data) +{ + struct xpm_state *h = data; + + fclose(h->infile); + free(h->charline); + free(h->rgbrow); + free(h->cmap); + free(h); +} + +/* ---------------------------------------------------------------------- */ + +struct xbm_state { + FILE *infile; + int width,height; +}; + +static void* +xbm_init(FILE *fp, char *filename, unsigned int page, + struct ida_image_info *info, int thumbnail) +{ + struct xbm_state *h; + char line[256],dummy[128]; + int i; + + h = malloc(sizeof(*h)); + memset(h,0,sizeof(*h)); + h->infile = fp; + + for (i = 0; i < 128; i++) { + fgets(line,sizeof(line)-1,fp); + if (0 == strncmp(line,"#define",7)) + break; + } + if (128 == i) + goto oops; + + if (2 != sscanf(line,"#define %127s %d",dummy,&h->width)) + goto oops; + fgets(line,sizeof(line)-1,fp); + if (2 != sscanf(line,"#define %127s %d",dummy,&h->height)) + goto oops; + if (debug) + fprintf(stderr,"xbm: %dx%d\n",h->width,h->height); + + for (i = 0; i < 4; i++) { + fgets(line,sizeof(line)-1,fp); + if (strstr(line,"[] = {")) + break; + } + if (4 == i) + goto oops; + + info->width = h->width; + info->height = h->height; + info->npages = 1; + return h; + + oops: + if (debug) + fprintf(stderr,"xbm: %s",line); + fclose(fp); + free(h); + return NULL; +} + +static void +xbm_read(unsigned char *dst, unsigned int line, void *data) +{ + struct xbm_state *h = data; + int x,val; + + for (x = 0; x < h->width; x++) { + if (0 == (x % 8)) + fscanf(h->infile," 0x%x,",&val); + if (val & (1 << (x % 8))) { + *(dst++) = 0; + *(dst++) = 0; + *(dst++) = 0; + } else { + *(dst++) = 255; + *(dst++) = 255; + *(dst++) = 255; + } + } +} + +static void +xbm_done(void *data) +{ + struct xpm_state *h = data; + + fclose(h->infile); + free(h); +} + +/* ---------------------------------------------------------------------- */ + +static struct ida_loader xpm_loader = { + magic: "/* XPM */", + moff: 0, + mlen: 9, + name: "xpm parser", + init: xpm_init, + read: xpm_read, + done: xpm_done, +}; + +static struct ida_loader xbm1_loader = { + magic: "#define", + moff: 0, + mlen: 7, + name: "xbm parser", + init: xbm_init, + read: xbm_read, + done: xbm_done, +}; + +static struct ida_loader xbm2_loader = { + magic: "/*", + moff: 0, + mlen: 2, + name: "xbm parser", + init: xbm_init, + read: xbm_read, + done: xbm_done, +}; + +static void __init init_rd(void) +{ + load_register(&xpm_loader); + load_register(&xbm1_loader); + load_register(&xbm2_loader); +} -- cgit