aboutsummaryrefslogtreecommitdiffstats
path: root/rd/read-xpm.c
diff options
context:
space:
mode:
authorkraxel <kraxel>2004-03-28 11:31:57 +0000
committerkraxel <kraxel>2004-03-28 11:31:57 +0000
commite9e9684117719204929821028ba9dbb7915ea119 (patch)
tree6dd2d71940b33a9f960945335e9124ef4fea9fe7 /rd/read-xpm.c
downloadfbida-e9e9684117719204929821028ba9dbb7915ea119.tar.gz
Initial revision
Diffstat (limited to 'rd/read-xpm.c')
-rw-r--r--rd/read-xpm.c287
1 files changed, 287 insertions, 0 deletions
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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <X11/Xlib.h>
+#include <X11/Intrinsic.h>
+
+#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);
+}