diff options
Diffstat (limited to 'src/xpm')
42 files changed, 9464 insertions, 0 deletions
diff --git a/src/xpm/Makefile b/src/xpm/Makefile new file mode 100644 index 0000000..4dcbff5 --- /dev/null +++ b/src/xpm/Makefile @@ -0,0 +1,28 @@ +# Makefile for the C library part of XPM needed by Icon. +# This file is a simplification of XPM's standard Makefile. + +include ../../Makedefs + +## if your system doesn't provide strcasecmp add -DNEED_STRCASECMP +## if your system doesn't provide pipe remove -DZPIPE + +RM = rm -f +AR = ar qc +RANLIB = ranlib +OBJS1 = data.o create.o misc.o rgb.o scan.o parse.o hashtable.o \ + XpmWrFFrP.o XpmRdFToP.o XpmCrPFData.o XpmCrDataFP.o \ + XpmWrFFrI.o XpmRdFToI.o XpmCrIFData.o XpmCrDataFI.o + +.c.o: + $(CC) -c $(CFLAGS) $(XPMDEFS) $*.c + + +libXpm.a: $(OBJS1) + $(RM) $@ + $(AR) $@ $(OBJS1) + $(RANLIB) $@ 2>/dev/null || : + +$(OBJS1): xpmP.h xpm.h + +Clean: + rm *.o *.a diff --git a/src/xpm/XpmCrDataFI.c b/src/xpm/XpmCrDataFI.c new file mode 100644 index 0000000..81c742b --- /dev/null +++ b/src/xpm/XpmCrDataFI.c @@ -0,0 +1,417 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* XpmCrDataFI.c: * +* * +* XPM library * +* Scan an image and possibly its mask and create an XPM array * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpmP.h" +#ifdef VMS +#include "sys$library:string.h" +#else +#if defined(SYSV) || defined(SVR4) +#include <string.h> +#else +#include <strings.h> +#endif +#endif + +LFUNC(CreateTransparentColor, int, (char **dataptr, unsigned int *data_size, + char **colors, unsigned int cpp, + unsigned int mask_pixel, + char ***colorTable)); + +LFUNC(CreateOtherColors, int, (char **dataptr, unsigned int *data_size, + char **colors, XColor *xcolors, + unsigned int ncolors, unsigned int cpp, + unsigned int mask_pixel, char ***colorTable, + unsigned int ncolors2, Pixel *pixels, + char *rgb_fname)); + +LFUNC(CreatePixels, void, (char **dataptr, unsigned int width, + unsigned int height, unsigned int cpp, + unsigned int *pixels, char **colors)); + +LFUNC(CountExtensions, void, (XpmExtension *ext, unsigned int num, + unsigned int *ext_size, + unsigned int *ext_nlines)); + +LFUNC(CreateExtensions, void, (char **dataptr, unsigned int offset, + XpmExtension *ext, unsigned int num, + unsigned int ext_nlines)); + +int +XpmCreateDataFromImage(display, data_return, image, shapeimage, attributes) + Display *display; + char ***data_return; + XImage *image; + XImage *shapeimage; + XpmAttributes *attributes; +{ + int ErrorStatus; + xpmInternAttrib attrib; + + /* + * initialize return values + */ + if (data_return) + *data_return = NULL; + + xpmInitInternAttrib(&attrib); + + /* + * Scan image then create data + */ + ErrorStatus = xpmScanImage(display, image, shapeimage, + attributes, &attrib); + + if (ErrorStatus == XpmSuccess) + ErrorStatus = xpmCreateData(data_return, &attrib, attributes); + + xpmFreeInternAttrib(&attrib); + + return (ErrorStatus); +} + + +#undef RETURN +#define RETURN(status) \ + { if (header) { \ + for (l = 0; l < header_nlines; l++) \ + if (header[l]) \ + free(header[l]); \ + free(header); \ + } \ + return(status); } + +int +xpmCreateData(data_return, attrib, attributes) + char ***data_return; + xpmInternAttrib *attrib; + XpmAttributes *attributes; +{ + /* calculation variables */ + int ErrorStatus; + char buf[BUFSIZ]; + char **header = NULL, **data, **sptr, **sptr2, *s; + unsigned int header_size, header_nlines; + unsigned int data_size, data_nlines; + unsigned int extensions = 0, ext_size = 0, ext_nlines = 0; + unsigned int infos = 0, offset, l, n; + + *data_return = NULL; + + infos = attributes && (attributes->valuemask & XpmInfos); + extensions = attributes && (attributes->valuemask & XpmExtensions) + && attributes->nextensions; + + /* compute the number of extensions lines and size */ + if (extensions) + CountExtensions(attributes->extensions, attributes->nextensions, + &ext_size, &ext_nlines); + + /* + * alloc a temporary array of char pointer for the header section which + * is the hints line + the color table lines + */ + header_nlines = 1 + attrib->ncolors; + header_size = sizeof(char *) * header_nlines; + header = (char **) calloc(header_size, sizeof(char *)); + if (!header) + RETURN(XpmNoMemory); + + /* + * print the hints line + */ + s = buf; + sprintf(s, "%d %d %d %d", attrib->width, attrib->height, + attrib->ncolors, attrib->cpp); + s += strlen(s); + + if (attributes && (attributes->valuemask & XpmHotspot)) { + sprintf(s, " %d %d", attributes->x_hotspot, attributes->y_hotspot); + s += strlen(s); + } + + if (extensions) + sprintf(s, " XPMEXT"); + + l = strlen(buf) + 1; + *header = (char *) malloc(l); + if (!*header) + RETURN(XpmNoMemory); + header_size += l; + strcpy(*header, buf); + + /* + * print colors + */ + + /* transparent color */ + if (attrib->mask_pixel != UNDEF_PIXEL) { + ErrorStatus = + CreateTransparentColor(header + 1, &header_size, + attrib->colorStrings, attrib->cpp, + (infos ? attributes->mask_pixel : 0), + (infos ? attributes->colorTable : NULL)); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + offset = 1; + } else + offset = 0; + + /* other colors */ + ErrorStatus = + CreateOtherColors(header + 1 + offset, &header_size, + attrib->colorStrings + offset, + attrib->xcolors + offset, attrib->ncolors - offset, + attrib->cpp, (infos ? attributes->mask_pixel : 0), + (infos ? attributes->colorTable : NULL), + (infos ? attributes->ncolors : 0), + (infos ? attributes->pixels : NULL), + (attributes && + (attributes->valuemask & XpmRgbFilename) ? + attributes->rgb_fname : NULL)); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + /* + * now we know the size needed, alloc the data and copy the header lines + */ + offset = attrib->width * attrib->cpp + 1; + data_size = header_size + (attrib->height + ext_nlines) * sizeof(char *) + + attrib->height * offset + ext_size; + + data = (char **) malloc(data_size); + if (!data) + RETURN(XpmNoMemory); + + data_nlines = header_nlines + attrib->height + ext_nlines; + *data = (char *) (data + data_nlines); + n = attrib->ncolors; + for (l = 0, sptr = data, sptr2 = header; l <= n; l++, sptr++, sptr2++) { + strcpy(*sptr, *sptr2); + *(sptr + 1) = *sptr + strlen(*sptr2) + 1; + } + + /* + * print pixels + */ + data[header_nlines] = (char *) data + header_size + + (attrib->height + ext_nlines) * sizeof(char *); + + CreatePixels(data + header_nlines, attrib->width, attrib->height, + attrib->cpp, attrib->pixelindex, attrib->colorStrings); + + /* + * print extensions + */ + if (extensions) + CreateExtensions(data + header_nlines + attrib->height - 1, offset, + attributes->extensions, attributes->nextensions, + ext_nlines); + + *data_return = data; + + RETURN(XpmSuccess); +} + + +static int +CreateTransparentColor(dataptr, data_size, colors, cpp, mask_pixel, colorTable) +char **dataptr; +unsigned int *data_size; +char **colors; +unsigned int cpp; +unsigned int mask_pixel; +char ***colorTable; +{ + char buf[BUFSIZ]; + unsigned int key, l; + char *s, *s2; + + strncpy(buf, *colors, cpp); + s = buf + cpp; + + if (colorTable && mask_pixel != UNDEF_PIXEL) { + for (key = 1; key <= NKEYS; key++) { + if (s2 = colorTable[mask_pixel][key]) { + sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2); + s += strlen(s); + } + } + } else + sprintf(s, "\tc %s", TRANSPARENT_COLOR); + + l = strlen(buf) + 1; + s = (char *) malloc(l); + if (!s) + return(XpmNoMemory); + *data_size += l; + strcpy(s, buf); + *dataptr = s; + return(XpmSuccess); +} + +static int +CreateOtherColors(dataptr, data_size, colors, xcolors, ncolors, cpp, + mask_pixel, colorTable, ncolors2, pixels, rgb_fname) +char **dataptr; +unsigned int *data_size; +char **colors; +XColor *xcolors; +unsigned int ncolors; +unsigned int cpp; +unsigned int mask_pixel; +char ***colorTable; +unsigned int ncolors2; +Pixel *pixels; +char *rgb_fname; +{ + char buf[BUFSIZ]; + unsigned int a, b, c, d, key, l; + char *s, *s2, *colorname; + xpmRgbName rgbn[MAX_RGBNAMES]; + int rgbn_max = 0; + + /* read the rgb file if any was specified */ + if (rgb_fname) + rgbn_max = xpmReadRgbNames(rgb_fname, rgbn); + + for (a = 0; a < ncolors; a++, colors++, xcolors++, dataptr++) { + + strncpy(buf, *colors, cpp); + s = buf + cpp; + + c = 1; + if (colorTable) { + d = 0; + for (b = 0; b < ncolors2; b++) { + if (b == mask_pixel) { + d = 1; + continue; + } + if (pixels[b - d] == xcolors->pixel) + break; + } + if (b != ncolors2) { + c = 0; + for (key = 1; key <= NKEYS; key++) { + if (s2 = colorTable[b][key]) { + sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2); + s += strlen(s); + } + } + } + } + if (c) { + colorname = NULL; + if (rgbn_max) + colorname = xpmGetRgbName(rgbn, rgbn_max, xcolors->red, + xcolors->green, xcolors->blue); + if (colorname) + sprintf(s, "\tc %s", colorname); + else + sprintf(s, "\tc #%04X%04X%04X", + xcolors->red, xcolors->green, xcolors->blue); + s += strlen(s); + } + l = strlen(buf) + 1; + s = (char *) malloc(l); + if (!s) + return(XpmNoMemory); + *data_size += l; + strcpy(s, buf); + *dataptr = s; + } + xpmFreeRgbNames(rgbn, rgbn_max); + return(XpmSuccess); +} + +static void +CreatePixels(dataptr, width, height, cpp, pixels, colors) +char **dataptr; +unsigned int width; +unsigned int height; +unsigned int cpp; +unsigned int *pixels; +char **colors; +{ + char *s; + unsigned int x, y, h, offset; + + h = height - 1; + offset = width * cpp + 1; + for (y = 0; /* test is inside loop */ ; y++, dataptr++) { + s = *dataptr; + for (x = 0; x < width; x++, pixels++) { + strncpy(s, colors[*pixels], cpp); + s += cpp; + } + *s = '\0'; + if (y >= h) + break; /* LEAVE LOOP */ + *(dataptr + 1) = *dataptr + offset; + } +} + +static void +CountExtensions(ext, num, ext_size, ext_nlines) +XpmExtension *ext; +unsigned int num; +unsigned int *ext_size; +unsigned int *ext_nlines; +{ + unsigned int x, y, a, size, nlines; + char **lines; + + size = 0; + nlines = 0; + for (x = 0; x < num; x++, ext++) { + /* "+ 2" is for the name and the ending 0 */ + nlines += ext->nlines + 2; + /* 8 = 7 (for "XPMEXT ") + 1 (for 0) */ + size += strlen(ext->name) + 8; + a = ext->nlines; + for (y = 0, lines = ext->lines; y < a; y++, lines++) + size += strlen(*lines) + 1; + } + *ext_size = size; + *ext_nlines = nlines; +} + +static void +CreateExtensions(dataptr, offset, ext, num, ext_nlines) +char **dataptr; +unsigned int offset; +XpmExtension *ext; +unsigned int num; +unsigned int ext_nlines; +{ + unsigned int x, y, a, b; + char **sptr; + + *(dataptr + 1) = *dataptr + offset; + dataptr++; + a = 0; + for (x = 0; x < num; x++, ext++) { + sprintf(*dataptr, "XPMEXT %s", ext->name); + a++; + if (a < ext_nlines) + *(dataptr + 1) = *dataptr + strlen(ext->name) + 8; + dataptr++; + b = ext->nlines; + for (y = 0, sptr = ext->lines; y < b; y++, sptr++) { + strcpy(*dataptr, *sptr); + a++; + if (a < ext_nlines) + *(dataptr + 1) = *dataptr + strlen(*sptr) + 1; + dataptr++; + } + } + *dataptr = 0; +} diff --git a/src/xpm/XpmCrDataFP.c b/src/xpm/XpmCrDataFP.c new file mode 100644 index 0000000..fd2e5e6 --- /dev/null +++ b/src/xpm/XpmCrDataFP.c @@ -0,0 +1,75 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* XpmCrDataFP.c: * +* * +* XPM library * +* Scan a pixmap and possibly its mask and create an XPM array * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpmP.h" +#ifdef VMS +#include "sys$library:string.h" +#else +#if defined(SYSV) || defined(SVR4) +#include <string.h> +#else +#include <strings.h> +#endif +#endif + +int +XpmCreateDataFromPixmap(display, data_return, pixmap, shapemask, attributes) + Display *display; + char ***data_return; + Pixmap pixmap; + Pixmap shapemask; + XpmAttributes *attributes; +{ + XImage *image = NULL; + XImage *shapeimage = NULL; + unsigned int width = 0; + unsigned int height = 0; + int ErrorStatus; + unsigned int dum; + int dummy; + Window win; + + /* + * get geometry + */ + if (attributes && attributes->valuemask & XpmSize) { + width = attributes->width; + height = attributes->height; + } else { + if (pixmap) + XGetGeometry(display, pixmap, &win, &dummy, &dummy, + &width, &height, &dum, &dum); + else if (shapemask) + XGetGeometry(display, shapemask, &win, &dummy, &dummy, + &width, &height, &dum, &dum); + } + + /* + * get the images + */ + if (pixmap) + image = XGetImage(display, pixmap, 0, 0, width, height, + AllPlanes, ZPixmap); + if (shapemask) + shapeimage = XGetImage(display, shapemask, 0, 0, width, height, + AllPlanes, ZPixmap); + + /* + * create data from images + */ + ErrorStatus = XpmCreateDataFromImage(display, data_return, image, + shapeimage, attributes); + if (image) + XDestroyImage(image); + if (shapeimage) + XDestroyImage(shapeimage); + + return (ErrorStatus); +} diff --git a/src/xpm/XpmCrIFData.c b/src/xpm/XpmCrIFData.c new file mode 100644 index 0000000..259bf47 --- /dev/null +++ b/src/xpm/XpmCrIFData.c @@ -0,0 +1,52 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* XpmCrIFData.c: * +* * +* XPM library * +* Parse an Xpm array and create the image and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpmP.h" + +int +XpmCreateImageFromData(display, data, image_return, + shapeimage_return, attributes) + Display *display; + char **data; + XImage **image_return; + XImage **shapeimage_return; + XpmAttributes *attributes; +{ + xpmData mdata; + int ErrorStatus; + xpmInternAttrib attrib; + + /* + * initialize return values + */ + if (image_return) + *image_return = NULL; + if (shapeimage_return) + *shapeimage_return = NULL; + + xpmOpenArray(data, &mdata); + xpmInitInternAttrib(&attrib); + + ErrorStatus = xpmParseData(&mdata, &attrib, attributes); + + if (ErrorStatus == XpmSuccess) + ErrorStatus = xpmCreateImage(display, &attrib, image_return, + shapeimage_return, attributes); + + if (ErrorStatus >= 0) + xpmSetAttributes(&attrib, attributes); + else if (attributes) + XpmFreeAttributes(attributes); + + xpmFreeInternAttrib(&attrib); + XpmDataClose(&mdata); + + return (ErrorStatus); +} diff --git a/src/xpm/XpmCrPFData.c b/src/xpm/XpmCrPFData.c new file mode 100644 index 0000000..dddb90e --- /dev/null +++ b/src/xpm/XpmCrPFData.c @@ -0,0 +1,92 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* XpmCrPFData.c: * +* * +* XPM library * +* Parse an Xpm array and create the pixmap and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpmP.h" + +int +XpmCreatePixmapFromData(display, d, data, pixmap_return, + shapemask_return, attributes) + Display *display; + Drawable d; + char **data; + Pixmap *pixmap_return; + Pixmap *shapemask_return; + XpmAttributes *attributes; +{ + XImage *image, **imageptr = NULL; + XImage *shapeimage, **shapeimageptr = NULL; + int ErrorStatus; + XGCValues gcv; + GC gc; + + /* + * initialize return values + */ + if (pixmap_return) { + *pixmap_return = 0; + imageptr = ℑ + } + if (shapemask_return) { + *shapemask_return = 0; + shapeimageptr = &shapeimage; + } + + /* + * create the images + */ + ErrorStatus = XpmCreateImageFromData(display, data, imageptr, + shapeimageptr, attributes); + if (ErrorStatus < 0) + return (ErrorStatus); + + /* + * create the pixmaps + */ + if (imageptr && image) { + *pixmap_return = XCreatePixmap(display, d, image->width, + image->height, image->depth); + gcv.function = GXcopy; + gc = XCreateGC(display, *pixmap_return, GCFunction, &gcv); + + XPutImage(display, *pixmap_return, gc, image, 0, 0, 0, 0, + image->width, image->height); + +#ifdef Debug + /* + * XDestroyImage free the image data but mnemosyne don't know about it + * so I free them by hand to avoid mnemalyse report it as lost data. + */ + free(image->data); +#endif + XDestroyImage(image); + XFreeGC(display, gc); + } + if (shapeimageptr && shapeimage) { + *shapemask_return = XCreatePixmap(display, d, shapeimage->width, + shapeimage->height, + shapeimage->depth); + gcv.function = GXcopy; + gc = XCreateGC(display, *shapemask_return, GCFunction, &gcv); + + XPutImage(display, *shapemask_return, gc, shapeimage, 0, 0, 0, 0, + shapeimage->width, shapeimage->height); + +#ifdef Debug + /* + * XDestroyImage free the image data but mnemosyne don't know about it + * so I free them by hand to avoid mnemalyse report it as lost data. + */ + free(shapeimage->data); +#endif + XDestroyImage(shapeimage); + XFreeGC(display, gc); + } + return (ErrorStatus); +} diff --git a/src/xpm/XpmRdFToData.c b/src/xpm/XpmRdFToData.c new file mode 100644 index 0000000..5d68e73 --- /dev/null +++ b/src/xpm/XpmRdFToData.c @@ -0,0 +1,115 @@ +/* Copyright 1990,91 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* XpmRdFToData.c: * +* * +* XPM library * +* Parse an XPM file and create an array of strings corresponding to it. * +* * +* Developed by Dan Greening dgreen@cs.ucla.edu / dgreen@sti.com * +\*****************************************************************************/ + +#include "xpmP.h" + +int +XpmReadFileToData(filename, data_return) + char *filename; + char ***data_return; +{ + xpmData mdata; + char buf[BUFSIZ]; + int l, n = 0; + XpmAttributes attributes; + xpmInternAttrib attrib; + int ErrorStatus; + XGCValues gcv; + GC gc; + + attributes.valuemask = XpmReturnPixels|XpmReturnInfos|XpmReturnExtensions; + /* + * initialize return values + */ + if (data_return) { + *data_return = NULL; + } + + if ((ErrorStatus = xpmReadFile(filename, &mdata)) != XpmSuccess) + return (ErrorStatus); + xpmInitInternAttrib(&attrib); + /* + * parse the header file + */ + mdata.Bos = '\0'; + mdata.Eos = '\n'; + mdata.Bcmt = mdata.Ecmt = NULL; + xpmNextWord(&mdata, buf); /* skip the first word */ + l = xpmNextWord(&mdata, buf); /* then get the second word */ + if ((l == 3 && !strncmp("XPM", buf, 3)) || + (l == 4 && !strncmp("XPM2", buf, 4))) { + if (l == 3) + n = 1; /* handle XPM as XPM2 C */ + else { + l = xpmNextWord(&mdata, buf); /* get the type key word */ + + /* + * get infos about this type + */ + while (xpmDataTypes[n].type + && strncmp(xpmDataTypes[n].type, buf, l)) + n++; + } + if (xpmDataTypes[n].type) { + if (n == 0) { /* natural type */ + mdata.Bcmt = xpmDataTypes[n].Bcmt; + mdata.Ecmt = xpmDataTypes[n].Ecmt; + xpmNextString(&mdata); /* skip the end of headerline */ + mdata.Bos = xpmDataTypes[n].Bos; + } else { + xpmNextString(&mdata); /* skip the end of headerline */ + mdata.Bcmt = xpmDataTypes[n].Bcmt; + mdata.Ecmt = xpmDataTypes[n].Ecmt; + mdata.Bos = xpmDataTypes[n].Bos; + mdata.Eos = '\0'; + xpmNextString(&mdata); /* skip the assignment line */ + } + mdata.Eos = xpmDataTypes[n].Eos; + + ErrorStatus = xpmParseData(&mdata, &attrib, &attributes); + } else + ErrorStatus = XpmFileInvalid; + } else + ErrorStatus = XpmFileInvalid; + + if (ErrorStatus == XpmSuccess) { + int i; + + /* maximum of allocated pixels will be the number of colors */ + attributes.pixels = (Pixel *) malloc(sizeof(Pixel) * attrib.ncolors); + attrib.xcolors = (XColor*) malloc(sizeof(XColor) * attrib.ncolors); + + if (!attributes.pixels || !attrib.xcolors) + ErrorStatus = XpmNoMemory; + else { + for (i = 0; i < attrib.ncolors; i++) { + /* Fake colors */ + attrib.xcolors[i].pixel = attributes.pixels[i] = i + 1; + } + xpmSetAttributes(&attrib, &attributes); + if (!(attrib.colorStrings = + (char**) malloc(attributes.ncolors * sizeof(char*)))) + ErrorStatus = XpmNoMemory; + else { + attrib.ncolors = attributes.ncolors; + attributes.mask_pixel = attrib.mask_pixel; + for (i = 0; i < attributes.ncolors; i++) + attrib.colorStrings[i] = attributes.colorTable[i][0]; + } + } + } + if (ErrorStatus == XpmSuccess) + ErrorStatus = xpmCreateData(data_return, &attrib, &attributes); + XpmFreeAttributes(&attributes); + xpmFreeInternAttrib(&attrib); + XpmDataClose(&mdata); + + return (ErrorStatus); +} diff --git a/src/xpm/XpmRdFToI.c b/src/xpm/XpmRdFToI.c new file mode 100644 index 0000000..af68f69 --- /dev/null +++ b/src/xpm/XpmRdFToI.c @@ -0,0 +1,110 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* XpmRdFToI.c: * +* * +* XPM library * +* Parse an XPM file and create the image and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpmP.h" + +xpmDataType xpmDataTypes[] = +{ + "", "!", "\n", '\0', '\n', "", "", "", "", /* Natural type */ + "C", "/*", "*/", '"', '"', ",\n", "static char *", "[] = {\n", "};\n", + "Lisp", ";", "\n", '"', '"', "\n", "(setq ", " '(\n", "))\n", +#ifdef VMS + NULL +#else + NULL, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL +#endif +}; + +int +XpmReadFileToImage(display, filename, image_return, + shapeimage_return, attributes) + Display *display; + char *filename; + XImage **image_return; + XImage **shapeimage_return; + XpmAttributes *attributes; +{ + xpmData mdata; + char buf[BUFSIZ]; + int l, n = 0; + int ErrorStatus; + xpmInternAttrib attrib; + + /* + * initialize return values + */ + if (image_return) + *image_return = NULL; + if (shapeimage_return) + *shapeimage_return = NULL; + + if ((ErrorStatus = xpmReadFile(filename, &mdata)) != XpmSuccess) + return (ErrorStatus); + + xpmInitInternAttrib(&attrib); + + /* + * parse the header file + */ + mdata.Bos = '\0'; + mdata.Eos = '\n'; + mdata.Bcmt = mdata.Ecmt = NULL; + xpmNextWord(&mdata, buf); /* skip the first word */ + l = xpmNextWord(&mdata, buf); /* then get the second word */ + if ((l == 3 && !strncmp("XPM", buf, 3)) || + (l == 4 && !strncmp("XPM2", buf, 4))) { + if (l == 3) + n = 1; /* handle XPM as XPM2 C */ + else { + l = xpmNextWord(&mdata, buf); /* get the type key word */ + + /* + * get infos about this type + */ + while (xpmDataTypes[n].type + && strncmp(xpmDataTypes[n].type, buf, l)) + n++; + } + if (xpmDataTypes[n].type) { + if (n == 0) { /* natural type */ + mdata.Bcmt = xpmDataTypes[n].Bcmt; + mdata.Ecmt = xpmDataTypes[n].Ecmt; + xpmNextString(&mdata); /* skip the end of headerline */ + mdata.Bos = xpmDataTypes[n].Bos; + } else { + xpmNextString(&mdata); /* skip the end of headerline */ + mdata.Bcmt = xpmDataTypes[n].Bcmt; + mdata.Ecmt = xpmDataTypes[n].Ecmt; + mdata.Bos = xpmDataTypes[n].Bos; + mdata.Eos = '\0'; + xpmNextString(&mdata); /* skip the assignment line */ + } + mdata.Eos = xpmDataTypes[n].Eos; + + ErrorStatus = xpmParseData(&mdata, &attrib, attributes); + + if (ErrorStatus == XpmSuccess) + ErrorStatus = xpmCreateImage(display, &attrib, image_return, + shapeimage_return, attributes); + } else + ErrorStatus = XpmFileInvalid; + } else + ErrorStatus = XpmFileInvalid; + + if (ErrorStatus >= 0) + xpmSetAttributes(&attrib, attributes); + else if (attributes) + XpmFreeAttributes(attributes); + + xpmFreeInternAttrib(&attrib); + XpmDataClose(&mdata); + + return (ErrorStatus); +} diff --git a/src/xpm/XpmRdFToP.c b/src/xpm/XpmRdFToP.c new file mode 100644 index 0000000..51732b5 --- /dev/null +++ b/src/xpm/XpmRdFToP.c @@ -0,0 +1,92 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* XpmRdFToP.c: * +* * +* XPM library * +* Parse an XPM file and create the pixmap and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpmP.h" + +int +XpmReadFileToPixmap(display, d, filename, pixmap_return, + shapemask_return, attributes) + Display *display; + Drawable d; + char *filename; + Pixmap *pixmap_return; + Pixmap *shapemask_return; + XpmAttributes *attributes; +{ + XImage *image, **imageptr = NULL; + XImage *shapeimage, **shapeimageptr = NULL; + int ErrorStatus; + XGCValues gcv; + GC gc; + + /* + * initialize return values + */ + if (pixmap_return) { + *pixmap_return = 0; + imageptr = ℑ + } + if (shapemask_return) { + *shapemask_return = 0; + shapeimageptr = &shapeimage; + } + + /* + * create the images + */ + ErrorStatus = XpmReadFileToImage(display, filename, imageptr, + shapeimageptr, attributes); + if (ErrorStatus < 0) + return (ErrorStatus); + + /* + * create the pixmaps + */ + if (imageptr && image) { + *pixmap_return = XCreatePixmap(display, d, image->width, + image->height, image->depth); + gcv.function = GXcopy; + gc = XCreateGC(display, *pixmap_return, GCFunction, &gcv); + + XPutImage(display, *pixmap_return, gc, image, 0, 0, 0, 0, + image->width, image->height); + +#ifdef Debug + /* + * XDestroyImage free the image data but mnemosyne don't know about it + * so I free them by hand to avoid mnemalyse report it as lost data. + */ + free(image->data); +#endif + XDestroyImage(image); + XFreeGC(display, gc); + } + if (shapeimageptr && shapeimage) { + *shapemask_return = XCreatePixmap(display, d, shapeimage->width, + shapeimage->height, + shapeimage->depth); + gcv.function = GXcopy; + gc = XCreateGC(display, *shapemask_return, GCFunction, &gcv); + + XPutImage(display, *shapemask_return, gc, shapeimage, 0, 0, 0, 0, + shapeimage->width, shapeimage->height); + +#ifdef Debug + /* + * XDestroyImage free the image data but mnemosyne don't know about it + * so I free them by hand to avoid mnemalyse report it as lost data. + */ + free(shapeimage->data); +#endif + XDestroyImage(shapeimage); + XFreeGC(display, gc); + } + return (ErrorStatus); +} diff --git a/src/xpm/XpmWrFFrData.c b/src/xpm/XpmWrFFrData.c new file mode 100644 index 0000000..3d567ec --- /dev/null +++ b/src/xpm/XpmWrFFrData.c @@ -0,0 +1,113 @@ +/* Copyright 1990,91 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* XpmWrFFrData.c: * +* * +* XPM library * +* Parse an Xpm array and write a file that corresponds to it. * +* * +* Developed by Dan Greening dgreen@cs.ucla.edu / dgreen@sti.com * +\*****************************************************************************/ + +#include "xpmP.h" +#ifdef VMS +#include "sys$library:string.h" +#else +#ifdef SYSV +#include <string.h> +#define index strchr +#define rindex strrchr +#else +#include <strings.h> +#endif +#endif + +int +XpmWriteFileFromData(filename, data) + char *filename; + char **data; +{ + xpmData mdata, mfile; + char *name, *dot, *s, *new_name = NULL; + int ErrorStatus; + XpmAttributes attributes; + xpmInternAttrib attrib; + int i; + + attributes.valuemask = XpmReturnPixels|XpmReturnInfos|XpmReturnExtensions; + if ((ErrorStatus = xpmWriteFile(filename, &mfile)) != XpmSuccess) + return (ErrorStatus); + + if (filename) { +#ifdef VMS + name = filename; +#else + if (!(name = rindex(filename, '/'))) + name = filename; + else + name++; +#endif + if (dot = index(name, '.')) { + new_name = (char*)strdup(name); + if (!new_name) { + new_name = NULL; + name = "image_name"; + } else { + /* change '.' to '_' to get a valid C syntax name */ + name = s = new_name; + while (dot = index(s, '.')) { + *dot = '_'; + s = dot; + } + } + } + } else + name = "image_name"; + + xpmInitInternAttrib(&attrib); + + /* + * Parse data then write it out + */ + + xpmOpenArray(data, &mdata); + + ErrorStatus = xpmParseData(&mdata, &attrib, &attributes); + if (ErrorStatus == XpmSuccess) { + attributes.mask_pixel = UNDEF_PIXEL; + + /* maximum of allocated pixels will be the number of colors */ + attributes.pixels = (Pixel *) malloc(sizeof(Pixel) * attrib.ncolors); + attrib.xcolors = (XColor*) malloc(sizeof(XColor) * attrib.ncolors); + + if (!attributes.pixels || !attrib.xcolors) + ErrorStatus == XpmNoMemory; + else { + int i; + + for (i = 0; i < attrib.ncolors; i++) { + /* Fake colors */ + attrib.xcolors[i].pixel = attributes.pixels[i] = i + 1; + } + xpmSetAttributes(&attrib, &attributes); + if (!(attrib.colorStrings = + (char**) malloc(attributes.ncolors * sizeof(char*)))) + ErrorStatus == XpmNoMemory; + else { + attrib.ncolors = attributes.ncolors; + for (i = 0; i < attributes.ncolors; i++) + attrib.colorStrings[i] = attributes.colorTable[i][0]; + + attrib.name = name; + ErrorStatus = xpmWriteData(&mfile, &attrib, &attributes); + } + } + } + if (new_name) + free(name); + XpmFreeAttributes(&attributes); + xpmFreeInternAttrib(&attrib); + XpmDataClose(&mfile); + XpmDataClose(&mdata); + + return (ErrorStatus); +} diff --git a/src/xpm/XpmWrFFrI.c b/src/xpm/XpmWrFFrI.c new file mode 100644 index 0000000..5b3706c --- /dev/null +++ b/src/xpm/XpmWrFFrI.c @@ -0,0 +1,341 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* XpmWrFFrI.c: * +* * +* XPM library * +* Write an image and possibly its mask to an XPM file * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpmP.h" +#ifdef VMS +#include "sys$library:string.h" +#else +#if defined(SYSV) || defined(SVR4) +#include <string.h> +#define index strchr +#define rindex strrchr +#else +#include <strings.h> +#endif +#endif + +LFUNC(WriteTransparentColor, void, (FILE *file, char **colors, + unsigned int cpp, unsigned int mask_pixel, + char ***colorTable)); + +LFUNC(WriteOtherColors, void, (FILE *file, char **colors, XColor *xcolors, + unsigned int ncolors, unsigned int cpp, + unsigned int mask_pixel, char ***colorTable, + unsigned int ncolors2, Pixel *pixels, + char *rgb_fname)); + +LFUNC(WritePixels, int, (FILE *file, unsigned int width, unsigned int height, + unsigned int cpp, unsigned int *pixels, + char **colors)); + +LFUNC(WriteExtensions, void, (FILE *file, XpmExtension *ext, + unsigned int num)); + +int +XpmWriteFileFromImage(display, filename, image, shapeimage, attributes) + Display *display; + char *filename; + XImage *image; + XImage *shapeimage; + XpmAttributes *attributes; +{ + xpmData mdata; + char *name, *dot, *s, *new_name = NULL; + int ErrorStatus; + xpmInternAttrib attrib; + + if ((ErrorStatus = xpmWriteFile(filename, &mdata)) != XpmSuccess) + return (ErrorStatus); + + if (filename) { +#ifdef VMS + name = filename; +#else + if (!(name = rindex(filename, '/'))) + name = filename; + else + name++; +#endif + if (dot = index(name, '.')) { + new_name = (char*)strdup(name); + if (!new_name) { + new_name = NULL; + name = "image_name"; + } else { + /* change '.' to '_' to get a valid C syntax name */ + name = s = new_name; + while (dot = index(s, '.')) { + *dot = '_'; + s = dot; + } + } + } + } else + name = "image_name"; + + xpmInitInternAttrib(&attrib); + + /* + * Scan image then write it out + */ + ErrorStatus = xpmScanImage(display, image, shapeimage, + attributes, &attrib); + + if (ErrorStatus == XpmSuccess) { + attrib.name = name; + ErrorStatus = xpmWriteData(&mdata, &attrib, attributes); + } + xpmFreeInternAttrib(&attrib); + XpmDataClose(&mdata); + if (new_name) + free(name); + + return (ErrorStatus); +} + + +int +xpmWriteData(mdata, attrib, attributes) + xpmData *mdata; + xpmInternAttrib *attrib; + XpmAttributes *attributes; +{ + /* calculation variables */ + unsigned int offset, infos; + FILE *file; + int ErrorStatus; + + /* store this to speed up */ + file = mdata->stream.file; + + infos = attributes && (attributes->valuemask & XpmInfos); + + /* + * print the header line + */ + fprintf(file, "/* XPM */\nstatic char * %s[] = {\n", attrib->name); + + /* + * print the hints line + */ + if (infos && attributes->hints_cmt) + fprintf(file, "/*%s*/\n", attributes->hints_cmt); + + fprintf(file, "\"%d %d %d %d", attrib->width, attrib->height, + attrib->ncolors, attrib->cpp); + + if (attributes && (attributes->valuemask & XpmHotspot)) + fprintf(file, " %d %d", attributes->x_hotspot, attributes->y_hotspot); + + if (attributes && (attributes->valuemask & XpmExtensions) + && attributes->nextensions) + fprintf(file, " XPMEXT"); + + fprintf(file, "\",\n"); + + /* + * print colors + */ + if (infos && attributes->colors_cmt) + fprintf(file, "/*%s*/\n", attributes->colors_cmt); + + /* transparent color */ + if (attrib->mask_pixel != UNDEF_PIXEL) { + WriteTransparentColor(file, attrib->colorStrings, attrib->cpp, + (infos ? attributes->mask_pixel : 0), + (infos ? attributes->colorTable : NULL)); + offset = 1; + } else + offset = 0; + + /* other colors */ + WriteOtherColors(file, attrib->colorStrings + offset, + attrib->xcolors + offset, attrib->ncolors - offset, + attrib->cpp, (infos ? attributes->mask_pixel : 0), + (infos ? attributes->colorTable : NULL), + (infos ? attributes->ncolors : 0), + (infos ? attributes->pixels : NULL), + (attributes && (attributes->valuemask & XpmRgbFilename) ? + attributes->rgb_fname : NULL)); + + /* + * print pixels + */ + if (infos && attributes->pixels_cmt) + fprintf(file, "/*%s*/\n", attributes->pixels_cmt); + + ErrorStatus = WritePixels(file, attrib->width, attrib->height, attrib->cpp, + attrib->pixelindex, attrib->colorStrings); + if (ErrorStatus != XpmSuccess) + return(ErrorStatus); + + /* + * print extensions + */ + if (attributes && (attributes->valuemask & XpmExtensions) + && attributes->nextensions) + WriteExtensions(file, attributes->extensions, attributes->nextensions); + + /* close the array */ + fprintf(file, "};\n"); + + return (XpmSuccess); +} + +static void +WriteTransparentColor(file, colors, cpp, mask_pixel, colorTable) +FILE *file; +char **colors; +unsigned int cpp; +unsigned int mask_pixel; +char ***colorTable; +{ + unsigned int key, i; + char *s; + + putc('"', file); + for (i = 0, s = *colors; i < cpp; i++, s++) + putc(*s, file); + + if (colorTable && mask_pixel != UNDEF_PIXEL) { + for (key = 1; key <= NKEYS; key++) { + if (s = colorTable[mask_pixel][key]) + fprintf(file, "\t%s %s", xpmColorKeys[key - 1], s); + } + } else + fprintf(file, "\tc %s", TRANSPARENT_COLOR); + + fprintf(file, "\",\n"); +} + +static void +WriteOtherColors(file, colors, xcolors, ncolors, cpp, mask_pixel, colorTable, + ncolors2, pixels, rgb_fname) +FILE *file; +char **colors; +XColor *xcolors; +unsigned int ncolors; +unsigned int cpp; +unsigned int mask_pixel; +char ***colorTable; +unsigned int ncolors2; +Pixel *pixels; +char *rgb_fname; +{ + unsigned int a, b, c, d, key; + char *s, *colorname; + xpmRgbName rgbn[MAX_RGBNAMES]; + int rgbn_max = 0; + + /* read the rgb file if any was specified */ + if (rgb_fname) + rgbn_max = xpmReadRgbNames(rgb_fname, rgbn); + + for (a = 0; a < ncolors; a++, colors++, xcolors++) { + + putc('"', file); + for (b = 0, s = *colors; b < cpp; b++, s++) + putc(*s, file); + + c = 1; + if (colorTable) { + d = 0; + for (b = 0; b < ncolors2; b++) { + if (b == mask_pixel) { + d = 1; + continue; + } + if (pixels[b - d] == xcolors->pixel) + break; + } + if (b != ncolors2) { + c = 0; + for (key = 1; key <= NKEYS; key++) { + if (s = colorTable[b][key]) + fprintf(file, "\t%s %s", xpmColorKeys[key - 1], s); + } + } + } + if (c) { + colorname = NULL; + if (rgbn_max) + colorname = xpmGetRgbName(rgbn, rgbn_max, xcolors->red, + xcolors->green, xcolors->blue); + if (colorname) + fprintf(file, "\tc %s", colorname); + else + fprintf(file, "\tc #%04X%04X%04X", xcolors->red, + xcolors->green, xcolors->blue); + } + fprintf(file, "\",\n"); + } + xpmFreeRgbNames(rgbn, rgbn_max); +} + + +static int +WritePixels(file, width, height, cpp, pixels, colors) +FILE *file; +unsigned int width; +unsigned int height; +unsigned int cpp; +unsigned int *pixels; +char **colors; +{ + char *s, *p, *buf; + unsigned int x, y, h; + + h = height - 1; + p = buf = (char *) malloc(width * cpp + 3); + *buf = '"'; + if (!buf) + return(XpmNoMemory); + p++; + for (y = 0; y < h; y++) { + s = p; + for (x = 0; x < width; x++, pixels++) { + strncpy(s, colors[*pixels], cpp); + s += cpp; + } + *s++ = '"'; + *s = '\0'; + fprintf(file, "%s,\n", buf); + } + /* duplicate some code to avoid a test in the loop */ + s = p; + for (x = 0; x < width; x++, pixels++) { + strncpy(s, colors[*pixels], cpp); + s += cpp; + } + *s++ = '"'; + *s = '\0'; + fprintf(file, "%s", buf); + + free(buf); + return(XpmSuccess); +} + +static void +WriteExtensions(file, ext, num) +FILE *file; +XpmExtension *ext; +unsigned int num; +{ + unsigned int x, y, n; + char **line; + + for (x = 0; x < num; x++, ext++) { + fprintf(file, ",\n\"XPMEXT %s\"", ext->name); + n = ext->nlines; + for (y = 0, line = ext->lines; y < n; y++, line++) + fprintf(file, ",\n\"%s\"", *line); + } + fprintf(file, ",\n\"XPMENDEXT\""); +} diff --git a/src/xpm/XpmWrFFrP.c b/src/xpm/XpmWrFFrP.c new file mode 100644 index 0000000..52eef29 --- /dev/null +++ b/src/xpm/XpmWrFFrP.c @@ -0,0 +1,75 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* XpmWrFFrP.c: * +* * +* XPM library * +* Write a pixmap and possibly its mask to an XPM file * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpmP.h" +#ifdef VMS +#include "sys$library:string.h" +#else +#if defined(SYSV) || defined(SVR4) +#include <string.h> +#else +#include <strings.h> +#endif +#endif + +int +XpmWriteFileFromPixmap(display, filename, pixmap, shapemask, attributes) + Display *display; + char *filename; + Pixmap pixmap; + Pixmap shapemask; + XpmAttributes *attributes; +{ + XImage *image = NULL; + XImage *shapeimage = NULL; + unsigned int width = 0; + unsigned int height = 0; + int ErrorStatus; + unsigned int dum; + int dummy; + Window win; + + /* + * get geometry + */ + if (attributes && attributes->valuemask & XpmSize) { + width = attributes->width; + height = attributes->height; + } else { + if (pixmap) + XGetGeometry(display, pixmap, &win, &dummy, &dummy, + &width, &height, &dum, &dum); + else if (shapemask) + XGetGeometry(display, shapemask, &win, &dummy, &dummy, + &width, &height, &dum, &dum); + } + + /* + * get the images + */ + if (pixmap) + image = XGetImage(display, pixmap, 0, 0, width, height, + AllPlanes, ZPixmap); + if (shapemask) + shapeimage = XGetImage(display, shapemask, 0, 0, width, height, + AllPlanes, ZPixmap); + + /* + * write them out + */ + ErrorStatus = XpmWriteFileFromImage(display, filename, image, shapeimage, + attributes); + if (image) + XDestroyImage(image); + if (shapeimage) + XDestroyImage(shapeimage); + + return (ErrorStatus); +} diff --git a/src/xpm/converters/ppm.README b/src/xpm/converters/ppm.README new file mode 100644 index 0000000..b5e254f --- /dev/null +++ b/src/xpm/converters/ppm.README @@ -0,0 +1,69 @@ +PPM Stuff +Convert portable pixmap to X11 Pixmap format (version 3) and vice versa +----------------------------------------------------------------------- + +The program ppmtoxpm is a modified version of one sent out by Mark Snitily +(mark@zok.uucp) and upgraded to XPM version 2 by Paul Breslaw +(paul@mecazh.uu.ch). + +It converts Jeff Poskanzer's (jef@well.sf.ca.us) portable pixmap format +(PBMPlus) into the new X11 pixmap format: XPM version 3 distributed by Arnaud +Le Hors (lehors@mirsa.inria.fr). + +It is built using the PBMPlus libraries in the same way as any of the +ppm utilities in the PBMPlus package. + +Paul Breslaw - Thu Nov 22 09:55:31 MET 1990 +-- +Paul Breslaw, Mecasoft SA, | telephone : 41 1 362 2040 +Guggachstrasse 10, CH-8057 Zurich, | e-mail : paul@mecazh.uu.ch +Switzerland. | mcsun!chx400!mecazh!paul +-- + +The program xpmtoppm is a modified version of the one distributed in the +PBMPlus package by Jeff Poskanzer's which converts XPM version 1 or 3 files +into a portable pixmap format. + +Upgraded to XPM version 3 by + Arnaud LE HORS BULL Research France -- Koala Project + lehors@sa.inria.fr Phone:(33) 93 65 77 71 Fax:(33) 93 65 77 66 + Inria Sophia Antipolis B.P.109 06561 Valbonne Cedex France + + +Installation +----------- +You should copy The ppmtoxpm.c, ppmtoxpm.1 and xpmtoppm.c, xpmtoppm.1 into +your .../pbmplus/ppm directory. + + +Patches +------- +* Rainer Sinkwitz sinkwitz@ifi.unizh.ch - 21 Nov 91: + +xpmtoppm.c: + - Bug fix, no advance of read ptr, would not read + colors like "ac c black" because it would find + the "c" of "ac" and then had problems with "c" + as color. + + - Now understands multword X11 color names + + - Now reads multiple color keys. Takes the color + of the hightest available key. Lines no longer need + to begin with key 'c'. + + - expanded line buffer to from 500 to 2048 for bigger files + +ppmtoxpm.c: + - Bug fix, should should malloc space for rgbn[j].name+1 in line 441 + caused segmentation faults + + - lowercase conversion of RGB names def'ed out, + considered harmful. + +Suggestions: + ppmtoxpm should read /usr/lib/X11/rgb.txt by default. + With the Imakefiles of pbmplus it even gets compiled + with -DRGB_DB=\"/usr/lib/X11/rgb.txt\" + + diff --git a/src/xpm/converters/ppmtoxpm.1 b/src/xpm/converters/ppmtoxpm.1 new file mode 100644 index 0000000..2b35fa6 --- /dev/null +++ b/src/xpm/converters/ppmtoxpm.1 @@ -0,0 +1,69 @@ +.TH ppmtoxpm 1 "Tue Apr 9 1991" +.SH NAME +ppmtoxpm - convert a portable pixmap into an X11 pixmap +.SH SYNOPSIS +ppmtoxpm [-name <xpmname>] [-rgb <rgb-textfile>] [<ppmfile>] +.SH DESCRIPTION +Reads a portable pixmap as input. +Produces X11 pixmap (version 3) as output which +can be loaded directly by the XPM library. +.PP +The \fB-name\f option allows one to specify the prefix string which is printed +in the resulting XPM output. If not specified, will default to the +filename (without extension) of the <ppmfile> argument. +If \fB-name\f is not specified and <ppmfile> +is not specified (i.e. piped input), the prefix string will default to +the string "noname". +.PP +The \fB-rgb\f option allows one to specify an X11 rgb text file for the +lookup of color name mnemonics. This rgb text file is typically the +/usr/lib/X11/rgb.txt of the MIT X11 distribution, but any file using the +same format may be used. When specified and +a RGB value from the ppm input matches a RGB value from the <rgb-textfile>, +then the corresponding color name mnemonic is printed in the XPM's colormap. +If \fB-rgb\f is not specified, or if the RGB values don't match, then the color +will be printed with the #RGB, #RRGGBB, #RRRGGGBBB, or #RRRRGGGGBBBB +hexadecimal format. +.PP +All flags can be abbreviated to their shortest unique prefix. +.PP +For example, to convert the file "dot" (found in /usr/include/X11/bitmaps), +from xbm to xpm one could specify +.IP +xbmtopbm dot | ppmtoxpm -name dot +.PP +or, with a rgb text file (in the local directory) +.IP +xbmtopbm dot | ppmtoxpm -name dot -rgb rgb.txt +.SH BUGS +An option to match the closest (rather than exact) color name mnemonic +from the rgb text would be a desirable enhancement. +.PP +Truncation of the least significant bits of a RGB value may result in +nonexact matches when performing color name mnemonic lookups. +.SH "SEE ALSO" +ppm(5) +.br +XPM Manual by Arnaud Le Hors lehors@mirsa.inria.fr +.SH AUTHOR +Copyright (C) 1990 by Mark W. Snitily. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, provided +that the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. This software is provided "as is" without express or +implied warranty. + +This tool was developed for Schlumberger Technologies, ATE Division, and +with their permission is being made available to the public with the above +copyright notice and permission notice. + +Upgraded to XPM2 by + Paul Breslaw, Mecasoft SA, Zurich, Switzerland (paul@mecazh.uu.ch) + Thu Nov 8 16:01:17 1990 + +Upgraded to XPM version 3 by + Arnaud Le Hors (lehors@mirsa.inria.fr) + Tue Apr 9 1991 + diff --git a/src/xpm/converters/ppmtoxpm.c b/src/xpm/converters/ppmtoxpm.c new file mode 100644 index 0000000..395b4a8 --- /dev/null +++ b/src/xpm/converters/ppmtoxpm.c @@ -0,0 +1,481 @@ +/* ppmtoxpm.c - read a portable pixmap and produce a (version 3) X11 pixmap +** +** Copyright (C) 1990 by Mark W. Snitily +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +** +** This tool was developed for Schlumberger Technologies, ATE Division, and +** with their permission is being made available to the public with the above +** copyright notice and permission notice. +** +** Upgraded to XPM2 by +** Paul Breslaw, Mecasoft SA, Zurich, Switzerland (paul@mecazh.uu.ch) +** Thu Nov 8 16:01:17 1990 +** +** Upgraded to XPM version 3 by +** Arnaud Le Hors (lehors@mirsa.inria.fr) +** Tue Apr 9 1991 +** +** Rainer Sinkwitz sinkwitz@ifi.unizh.ch - 21 Nov 91: +** - Bug fix, should should malloc space for rgbn[j].name+1 in line 441 +** caused segmentation faults +** +** - lowercase conversion of RGB names def'ed out, +** considered harmful. +*/ + +#include <stdio.h> +#include <ctype.h> +#include "ppm.h" +#include "ppmcmap.h" + +#if defined(SYSV) || defined(SVR4) +#include <string.h> +#ifndef index +#define index strchr +#endif +#else /* SYSV */ +#include <strings.h> +#endif /* SYSV */ + +/* Max number of colors allowed in ppm input. */ +#define MAXCOLORS 256 + +/* Max number of rgb mnemonics allowed in rgb text file. */ +#define MAX_RGBNAMES 1024 + +/* Lower bound and upper bound of character-pixels printed in XPM output. + Be careful, don't want the character '"' in this range. */ +/*#define LOW_CHAR '#' <-- minimum ascii character allowed */ +/*#define HIGH_CHAR '~' <-- maximum ascii character allowed */ +#define LOW_CHAR '`' +#define HIGH_CHAR 'z' + +#define max(a,b) ((a) > (b) ? (a) : (b)) + +void read_rgb_names(); /* forward reference */ +void gen_cmap(); /* forward reference */ + +typedef struct { /* rgb values and ascii names (from + * rgb text file) */ + int r, g, b; /* rgb values, range of 0 -> 65535 */ + char *name; /* color mnemonic of rgb value */ +} rgb_names; + +typedef struct { /* character-pixel mapping */ + char *cixel; /* character string printed for + * pixel */ + char *rgbname; /* ascii rgb color, either color + * mnemonic or #rgb value */ +} cixel_map; + +pixel **pixels; + +main(argc, argv) + int argc; + char *argv[]; + +{ + FILE *ifd; + register pixel *pP; + int argn, rows, cols, ncolors, row, col, i; + pixval maxval; /* pixval == unsigned char or + * unsigned short */ + colorhash_table cht; + colorhist_vector chv; + + /* Used for rgb value -> rgb mnemonic mapping */ + int map_rgb_names = 0; + rgb_names rgbn[MAX_RGBNAMES]; + int rgbn_max; + + /* Used for rgb value -> character-pixel string mapping */ + cixel_map cmap[MAXCOLORS]; + int charspp; /* chars per pixel */ + + char out_name[100], rgb_fname[100], *cp; + char *usage = "[-name <xpm-name>] [-rgb <rgb-textfile>] [ppmfile]"; + + ppm_init(&argc, argv); + out_name[0] = rgb_fname[0] = '\0'; + + argn = 1; + + /* Check for command line options. */ + while (argn < argc && argv[argn][0] == '-') { + + /* Case "-", use stdin for input. */ + if (argv[argn][1] == '\0') + break; + + /* Case "-name <xpm-filename>", get output filename. */ + if (strncmp(argv[argn], "-name", max(strlen(argv[argn]), 2)) == 0) { + argn++; + if (argn == argc || sscanf(argv[argn], "%s", out_name) != 1) + pm_usage(usage); + } + /* Case "-rgb <rgb-filename>", get rgb mnemonics filename. */ + else if (strncmp(argv[argn], "-rgb", max(strlen(argv[argn]), 2)) == 0) { + argn++; + if (argn == argc || sscanf(argv[argn], "%s", rgb_fname) != 1) + pm_usage(usage); + map_rgb_names = 1; + } + /* Nothing else allowed... */ + else + pm_usage(usage); + + argn++; + } + + /* Input file specified, open it and set output filename if necessary. */ + if (argn < argc) { + + /* Open the input file. */ + ifd = pm_openr(argv[argn]); + + /* If output filename not specified, use input filename as default. */ + if (out_name[0] == '\0') { + strcpy(out_name, argv[argn]); + if (cp = index(out_name, '.')) + *cp = '\0'; /* remove extension */ + } + + /* + * If (1) input file was specified as "-" we're using stdin, or (2) + * output filename was specified as "-", set output filename to the + * default. + */ + if (!strcmp(out_name, "-")) + strcpy(out_name, "noname"); + + argn++; + } + /* No input file specified. Using stdin so set default output filename. */ + else { + ifd = stdin; + if (out_name[0] == '\0') + strcpy(out_name, "noname"); + } + + /* Only 0 or 1 input files allowed. */ + if (argn != argc) + pm_usage(usage); + + /* + * "maxval" is the largest value that can be be found in the ppm file. + * All pixel components are relative to this value. + */ + pixels = ppm_readppm(ifd, &cols, &rows, &maxval); + pm_close(ifd); + + /* Figure out the colormap. */ + fprintf(stderr, "(Computing colormap..."); + fflush(stderr); + chv = ppm_computecolorhist(pixels, cols, rows, MAXCOLORS, &ncolors); + if (chv == (colorhist_vector) 0) + pm_error( + "too many colors - try running the pixmap through 'ppmquant 256'", + 0, 0, 0, 0, 0); + fprintf(stderr, " Done. %d colors found.)\n", ncolors); + + /* Make a hash table for fast color lookup. */ + cht = ppm_colorhisttocolorhash(chv, ncolors); + + /* + * If a rgb text file was specified, read in the rgb mnemonics. Does not + * return if fatal error occurs. + */ + if (map_rgb_names) + read_rgb_names(rgb_fname, rgbn, &rgbn_max); + + /* Now generate the character-pixel colormap table. */ + gen_cmap(chv, ncolors, maxval, map_rgb_names, rgbn, rgbn_max, + cmap, &charspp); + + /* Write out the XPM file. */ + + printf("/* XPM */\n"); + printf("static char *%s[] = {\n", out_name); + printf("/* width height ncolors chars_per_pixel */\n"); + printf("\"%d %d %d %d\",\n", cols, rows, ncolors, charspp); + printf("/* colors */\n"); + for (i = 0; i < ncolors; i++) { + printf("\"%s c %s\",\n", cmap[i].cixel, cmap[i].rgbname); + } + printf("/* pixels */\n"); + for (row = 0; row < rows; row++) { + printf("\""); + for (col = 0, pP = pixels[row]; col < cols; col++, pP++) { + printf("%s", cmap[ppm_lookupcolor(cht, pP)].cixel); + } + printf("\"%s\n", (row == (rows - 1) ? "" : ",")); + } + printf("};\n"); + + exit(0); + +} /* main */ + +/*---------------------------------------------------------------------------*/ +/* This routine reads a rgb text file. It stores the rgb values (0->65535) + and the rgb mnemonics (malloc'ed) into the "rgbn" array. Returns the + number of entries stored in "rgbn_max". */ +void +read_rgb_names(rgb_fname, rgbn, rgbn_max) + char *rgb_fname; + rgb_names rgbn[MAX_RGBNAMES]; +int *rgbn_max; + +{ + FILE *rgbf; + int i, items, red, green, blue; + char line[512], name[512], *rgbname, *n, *m; + + /* Open the rgb text file. Abort if error. */ + if ((rgbf = fopen(rgb_fname, "r")) == NULL) + pm_error("error opening rgb text file \"%s\"", rgb_fname, 0, 0, 0, 0); + + /* Loop reading each line in the file. */ + for (i = 0; fgets(line, sizeof(line), rgbf); i++) { + + /* Quit if rgb text file is too large. */ + if (i == MAX_RGBNAMES) { + fprintf(stderr, + "Too many entries in rgb text file, truncated to %d entries.\n", + MAX_RGBNAMES); + fflush(stderr); + break; + } + /* Read the line. Skip if bad. */ + items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name); + if (items != 4) { + fprintf(stderr, "rgb text file syntax error on line %d\n", i + 1); + fflush(stderr); + i--; + continue; + } + /* Make sure rgb values are within 0->255 range. Skip if bad. */ + if (red < 0 || red > 0xFF || + green < 0 || green > 0xFF || + blue < 0 || blue > 0xFF) { + fprintf(stderr, "rgb value for \"%s\" out of range, ignoring it\n", + name); + fflush(stderr); + i--; + continue; + } + /* Allocate memory for ascii name. Abort if error. */ + if (!(rgbname = (char *) malloc(strlen(name) + 1))) + pm_error("out of memory allocating rgb name", 0, 0, 0, 0, 0); + +#ifdef NAMESLOWCASE + /* Copy string to ascii name and lowercase it. */ + for (n = name, m = rgbname; *n; n++) + *m++ = isupper(*n) ? tolower(*n) : *n; + *m = '\0'; +#else + strcpy(rgbname, name); +#endif + + /* Save the rgb values and ascii name in the array. */ + rgbn[i].r = red << 8; + rgbn[i].g = green << 8; + rgbn[i].b = blue << 8; + rgbn[i].name = rgbname; + } + + /* Return the max number of rgb names. */ + *rgbn_max = i - 1; + + fclose(rgbf); + +} /* read_rgb_names */ + +/*---------------------------------------------------------------------------*/ +/* Given a number and a base, (base == HIGH_CHAR-LOW_CHAR+1), this routine + prints the number into a malloc'ed string and returns it. The length of + the string is specified by "digits". The ascii characters of the printed + number range from LOW_CHAR to HIGH_CHAR. The string is LOW_CHAR filled, + (e.g. if LOW_CHAR==0, HIGH_CHAR==1, digits==5, i=3, routine would return + the malloc'ed string "00011"). */ +char * +gen_numstr(i, base, digits) + int i, base, digits; +{ + char *str, *p; + int d; + + /* Allocate memory for printed number. Abort if error. */ + if (!(str = (char *) malloc(digits + 1))) + pm_error("out of memory", 0, 0, 0, 0, 0); + + /* Generate characters starting with least significant digit. */ + p = str + digits; + *p-- = '\0'; /* nul terminate string */ + while (p >= str) { + d = i % base; + i /= base; + *p-- = (char) ((int) LOW_CHAR + d); + } + + return str; + +} /* gen_numstr */ + +/*---------------------------------------------------------------------------*/ +/* This routine generates the character-pixel colormap table. */ +void +gen_cmap(chv, ncolors, maxval, map_rgb_names, rgbn, rgbn_max, + cmap, charspp) +/* input: */ + colorhist_vector chv; /* contains rgb values for colormap */ + int ncolors; /* number of entries in colormap */ + pixval maxval; /* largest color value, all rgb + * values relative to this, (pixval + * == unsigned short) */ + int map_rgb_names; /* == 1 if mapping rgb values to rgb + * mnemonics */ + rgb_names rgbn[MAX_RGBNAMES]; /* rgb mnemonics from rgb text file */ +int rgbn_max; /* number of rgb mnemonics in table */ + +/* output: */ +cixel_map cmap[MAXCOLORS]; /* pixel strings and ascii rgb + * colors */ +int *charspp; /* characters per pixel */ + +{ + int i, j, base, cpp, mval, red, green, blue, r, g, b, matched; + char *str; + + /* + * Figure out how many characters per pixel we'll be using. Don't want + * to be forced to link with libm.a, so using a division loop rather + * than a log function. + */ + base = (int) HIGH_CHAR - (int) LOW_CHAR + 1; + for (cpp = 0, j = ncolors; j; cpp++) + j /= base; + *charspp = cpp; + + /* + * Determine how many hex digits we'll be normalizing to if the rgb + * value doesn't match a color mnemonic. + */ + mval = (int) maxval; + if (mval <= 0x000F) + mval = 0x000F; + else if (mval <= 0x00FF) + mval = 0x00FF; + else if (mval <= 0x0FFF) + mval = 0x0FFF; + else + mval = 0xFFFF; + + /* + * Generate the character-pixel string and the rgb name for each + * colormap entry. + */ + for (i = 0; i < ncolors; i++) { + + /* + * The character-pixel string is simply a printed number in base + * "base" where the digits of the number range from LOW_CHAR to + * HIGH_CHAR and the printed length of the number is "cpp". + */ + cmap[i].cixel = gen_numstr(i, base, cpp); + + /* Fetch the rgb value of the current colormap entry. */ + red = PPM_GETR(chv[i].color); + green = PPM_GETG(chv[i].color); + blue = PPM_GETB(chv[i].color); + + /* + * If the ppm color components are not relative to 15, 255, 4095, + * 65535, normalize the color components here. + */ + if (mval != (int) maxval) { + red = (red * mval) / (int) maxval; + green = (green * mval) / (int) maxval; + blue = (blue * mval) / (int) maxval; + } + + /* + * If the "-rgb <rgbfile>" option was specified, attempt to map the + * rgb value to a color mnemonic. + */ + if (map_rgb_names) { + + /* + * The rgb values of the color mnemonics are normalized relative + * to 255 << 8, (i.e. 0xFF00). [That's how the original MIT + * code did it, really should have been "v * 65535 / 255" + * instead of "v << 8", but have to use the same scheme here or + * else colors won't match...] So, if our rgb values aren't + * already 16-bit values, need to shift left. + */ + if (mval == 0x000F) { + r = red << 12; + g = green << 12; + b = blue << 12; + /* Special case hack for "white". */ + if (0xF000 == r && r == g && g == b) + r = g = b = 0xFF00; + } else if (mval == 0x00FF) { + r = red << 8; + g = green << 8; + b = blue << 8; + } else if (mval == 0x0FFF) { + r = red << 4; + g = green << 4; + b = blue << 4; + } else { + r = red; + g = green; + b = blue; + } + + /* + * Just perform a dumb linear search over the rgb values of the + * color mnemonics. One could speed things up by sorting the + * rgb values and using a binary search, or building a hash + * table, etc... + */ + for (matched = 0, j = 0; j <= rgbn_max; j++) + if (r == rgbn[j].r && g == rgbn[j].g && b == rgbn[j].b) { + + /* Matched. Allocate string, copy mnemonic, and exit. */ + if (!(str = (char *) malloc(strlen(rgbn[j].name) + 1))) + pm_error("out of memory", 0, 0, 0, 0, 0); + strcpy(str, rgbn[j].name); + cmap[i].rgbname = str; + matched = 1; + break; + } + if (matched) + continue; + } + + /* + * Either not mapping to color mnemonics, or didn't find a match. + * Generate an absolute #RGB value string instead. + */ + if (!(str = (char *) malloc(mval == 0x000F ? 5 : + mval == 0x00FF ? 8 : + mval == 0x0FFF ? 11 : + 14))) + pm_error("out of memory", 0, 0, 0, 0, 0); + + sprintf(str, mval == 0x000F ? "#%X%X%X" : + mval == 0x00FF ? "#%02X%02X%02X" : + mval == 0x0FFF ? "#%03X%03X%03X" : + "#%04X%04X%04X", red, green, blue); + cmap[i].rgbname = str; + } + +} /* gen_cmap */ diff --git a/src/xpm/converters/xpm1to3.pl b/src/xpm/converters/xpm1to3.pl new file mode 100644 index 0000000..d102964 --- /dev/null +++ b/src/xpm/converters/xpm1to3.pl @@ -0,0 +1,90 @@ +#!/usr/local/bin/perl +# +# Usage: xpm1to3.pl xpmv1-file > xpmv3-file +# +# Note: perl (available by ftp on prep.ai.mit.edu) script to convert +# "enhanced" xpm v1 X11 pixmap files to xpm v3 (C includable format) +# pixmap files... +# +--------------------------------------------------------------------------- +# WHO: Richard Hess CORP: Consilium +# TITLE: Staff Engineer VOICE: [415] 691-6342 +# [ X-SWAT Team: Special Projects ] USNAIL: 640 Clyde Court +# UUCP: ...!uunet!cimshop!rhess Mountain View, CA 94043 +# +--------------------------------------------------------------------------- + +sub checkname { + if ($_[0] ne $_[1]) { + printf STDERR "warning, name inconsitencies in %s %s!=%s\n", + $_[2], $_[0], $_[1]; + } +} + +sub checkmono { + if ($_[0] ne $_[1]) { return 0; } + return 1; +} + +printf "/* XPM */\n"; +($name, $format) = (<> =~ /^#define\s+(\w+)_format\s+(\d+)\s*$/); +($name2, $width) = (<> =~ /^#define\s+(\w+)_width\s+(\d+)\s*$/); +&checkname($name, $name2, "width"); +($name2, $height) = (<> =~ /^#define\s+(\w+)_height\s+(\d+)\s*$/); +&checkname($name, $name2, "height"); +($name2, $ncolors) = (<> =~ /^#define\s+(\w+)_ncolors\s+(\d+)\s*$/); +&checkname($name, $name2, "ncolors"); +($name2, $chars_per_pixel) = (<> =~ +/^#define\s+(\w+)_chars_per_pixel\s+(\d+)\s*$/); +&checkname($name, $name2, "chars per pixel"); + +($name2) = (<> =~ /^static char \*\s*(\w+)_mono\[]\s+=\s+{\s*$/); +$mono = &checkmono($name, $name2); + +if ($mono) { + $idx = 0; + while ( ($_ = <>) =~ m/^\s*"[^"]+"\s*,\s*"[^"]+"(,)?\s*$/ ) { + ($codes[$idx], $mono_name[$idx]) = /^\s*"([^"]+)"\s*,\s*"([^"]+)"(,)?\s*$/; + $idx++; + } + if ($idx != $ncolors) { + printf STDERR "Warning, ncolors mismatch reading mono %d != %d\n", +$ncolors, $idx; + } + + ($name2) = (<> =~ /^static char \*\s*(\w+)_colors\[]\s+=\s+{\s*$/); + &checkname($name, $name2, "colors"); +} + +printf "static char * %s[] = {\n", $name; +printf "/* %s pixmap\n * width height ncolors chars_per_pixel */\n", $name; +printf "\"%s %s %s %s \",\n", $width, $height, $ncolors, $chars_per_pixel; + +$idx = 0; +while ( ($_ = <>) =~ m/^\s*"[^"]+"\s*,\s*"[^"]+"(,)?\s*$/ ) { + ($codes[$idx], $color_name[$idx]) = /^\s*"([^"]+)"\s*,\s*"([^"]+)"(,)?\s*$/; + $idx++; +} +if ($idx != $ncolors) { + printf STDERR "Warning, ncolors mismatch reading color %d != %d\n", +$ncolors, $idx; +} + +for ($idx=0; $idx<$ncolors; $idx++) { + if ($mono) { + printf "\"%s m %s c %s \t s c%d \",\n", $codes[$idx], +$mono_name[$idx], $color_name[$idx], $idx; + } + else { + printf "\"%s c %s \t s c%d \",\n", $codes[$idx], $color_name[$idx], $idx; + } +} + +($name2) = ( <> =~ /^static char \*\s*(\w+)_pixels\[]\s+=\s+{\s*$/); +&checkname($name, $name2, "pixels"); + +printf "/* pixels */\n"; +while ( ! ( ($_ = <>) =~ /^}\s*;\s*$/) ) { + printf "%s", $_; +} +printf "} ;\n"; + +# -----------------------------------------------------------------------<eof> diff --git a/src/xpm/converters/xpmtoppm.1 b/src/xpm/converters/xpmtoppm.1 new file mode 100644 index 0000000..e4f414c --- /dev/null +++ b/src/xpm/converters/xpmtoppm.1 @@ -0,0 +1,28 @@ +.TH xpmtoppm 1 "16 August 1990" +.SH NAME +xpmtoppm - convert an X11 pixmap into a portable pixmap +.SH SYNOPSIS +.B xpmtoppm +.RI [ xpmfile ] +.SH DESCRIPTION +Reads an X11 pixmap (XPM version 1 or 3) as input. +Produces a portable pixmap as output. +.SH KNOWN BUGS +The support to XPM version 3 is limited. Comments can only be single lines +and there must be for every pixel a default colorname for a color type visual. +.SH "SEE ALSO" +ppmtoxpm(1), ppm(5) +.br +XPM Manual by Arnaud Le Hors lehors@mirsa.inria.fr +.SH AUTHOR +Copyright (C) 1991 by Jef Poskanzer. +.\" Permission to use, copy, modify, and distribute this software and its +.\" documentation for any purpose and without fee is hereby granted, provided +.\" that the above copyright notice appear in all copies and that both that +.\" copyright notice and this permission notice appear in supporting +.\" documentation. This software is provided "as is" without express or +.\" implied warranty. + +Upgraded to support XPM version 3 by + Arnaud Le Hors (lehors@mirsa.inria.fr) + Tue Apr 9 1991 diff --git a/src/xpm/converters/xpmtoppm.c b/src/xpm/converters/xpmtoppm.c new file mode 100644 index 0000000..9842267 --- /dev/null +++ b/src/xpm/converters/xpmtoppm.c @@ -0,0 +1,433 @@ +/* xpmtoppm.c - read an X11 pixmap file and produce a portable pixmap +** +** Copyright (C) 1991 by Jef Poskanzer. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +** +** Upgraded to support XPM version 3 by +** Arnaud Le Hors (lehors@mirsa.inria.fr) +** Tue Apr 9 1991 +** +** Rainer Sinkwitz sinkwitz@ifi.unizh.ch - 21 Nov 91: +** - Bug fix, no advance of read ptr, would not read +** colors like "ac c black" because it would find +** the "c" of "ac" and then had problems with "c" +** as color. +** +** - Now understands multword X11 color names +** +** - Now reads multiple color keys. Takes the color +** of the hightest available key. Lines no longer need +** to begin with key 'c'. +** +** - expanded line buffer to from 500 to 2048 for bigger files +*/ + +#include "ppm.h" + +void ReadXPMFile(); +static void getline(); + +/* number of xpmColorKeys */ +#define NKEYS 5 + +char *xpmColorKeys[] = +{ + "s", /* key #1: symbol */ + "m", /* key #2: mono visual */ + "g4", /* key #3: 4 grays visual */ + "g", /* key #4: gray visual */ + "c", /* key #5: color visual */ +}; + +#ifdef NEED_STRSTR +/* for systems which do not provide it */ +static char * +strstr(s1, s2) + char *s1, *s2; +{ + int ls2 = strlen(s2); + + if (ls2 == 0) + return (s1); + while (strlen(s1) >= ls2) { + if (strncmp(s1, s2, ls2) == 0) + return (s1); + s1++; + } + return (0); +} + +#endif + +void +main(argc, argv) + int argc; + char *argv[]; + +{ + FILE *ifp; + pixel *pixrow, *colors; + register pixel *pP; + int rows, cols, ncolors, chars_per_pixel, row; + register int col; + int *data; + register int *ptr; + + ppm_init(&argc, argv); + + if (argc > 2) + pm_usage("[xpmfile]"); + + if (argc == 2) + ifp = pm_openr(argv[1]); + else + ifp = stdin; + + ReadXPMFile( + ifp, &cols, &rows, &ncolors, &chars_per_pixel, &colors, &data); + + pm_close(ifp); + + ppm_writeppminit(stdout, cols, rows, (pixval) PPM_MAXMAXVAL, 0); + pixrow = ppm_allocrow(cols); + + for (row = 0, ptr = data; row < rows; ++row) { + for (col = 0, pP = pixrow; col < cols; ++col, ++pP, ++ptr) + *pP = colors[*ptr]; + ppm_writeppmrow(stdout, pixrow, cols, (pixval) PPM_MAXMAXVAL, 0); + } + + exit(0); +} + +#define MAX_LINE 2048 + +void +ReadXPMFile(stream, widthP, heightP, ncolorsP, + chars_per_pixelP, colorsP, dataP) + FILE *stream; + int *widthP; + int *heightP; + int *ncolorsP; + int *chars_per_pixelP; + pixel **colorsP; + int **dataP; +{ + char line[MAX_LINE], str1[MAX_LINE], str2[MAX_LINE]; + char *t1; + char *t2; + int format, v, datasize; + int *ptr; + int *ptab; + register int i, j; + int flag; + + unsigned int curkey, key, highkey; /* current color key */ + unsigned int lastwaskey; /* key read */ + char curbuf[BUFSIZ]; /* current buffer */ + + *widthP = *heightP = *ncolorsP = *chars_per_pixelP = format = -1; + flag = 0; /* to avoid getting twice a line */ + + /* First try to read as an XPM version 3 file */ + + /* Read the header line */ + getline(line, sizeof(line), stream); + if (sscanf(line, "/* %s */", str1) == 1 + && !strncmp(str1, "XPM", 3)) { + + /* Read the assignment line */ + getline(line, sizeof(line), stream); + if (strncmp(line, "static char", 11)) + pm_error("error scanning assignment line", 0, 0, 0, 0, 0); + + /* Read the hints line */ + getline(line, sizeof(line), stream); + /* skip the comment line if any */ + if (!strncmp(line, "/*", 2)) { + while (!strstr(line, "*/")) + getline(line, sizeof(line), stream); + getline(line, sizeof(line), stream); + } + if (sscanf(line, "\"%d %d %d %d\",", widthP, heightP, + ncolorsP, chars_per_pixelP) != 4) + pm_error("error scanning hints line", 0, 0, 0, 0, 0); + + /* Allocate space for color table. */ + if (*chars_per_pixelP <= 2) { + /* Up to two chars per pixel, we can use an indexed table. */ + v = 1; + for (i = 0; i < *chars_per_pixelP; ++i) + v *= 256; + *colorsP = ppm_allocrow(v); + } else { + /* Over two chars per pixel, we fall back on linear search. */ + *colorsP = ppm_allocrow(*ncolorsP); + ptab = (int *) malloc(*ncolorsP * sizeof(int)); + } + + /* Read the color table */ + for (i = 0; i < *ncolorsP; i++) { + getline(line, sizeof(line), stream); + /* skip the comment line if any */ + if (!strncmp(line, "/*", 2)) + getline(line, sizeof(line), stream); + + /* read the chars */ + if ((t1 = index(line, '"')) == NULL) + pm_error("error scanning color table", 0, 0, 0, 0, 0); + else + t1++; + strncpy(str1, t1, *chars_per_pixelP); + str1[*chars_per_pixelP] = '\0'; + t1++; t1++; + + v = 0; + for (j = 0; j < *chars_per_pixelP; ++j) + v = (v << 8) + str1[j]; + /* + * read color keys and values + */ + curkey = 0; + highkey = 1; + lastwaskey = 0; + t2 = t1; + while ( 1 ) { + for (t1=t2 ;; t1++) + if (*t1 != ' ' && *t1 != ' ') + break; + for (t2 = t1;; t2++) + if (*t2 == ' ' || *t2 == ' ' || *t2 == '"') + break; + if (t2 == t1) break; + strncpy(str2, t1, t2 - t1); + str2[t2 - t1] = '\0'; + + if (!lastwaskey) { + for (key = 1; key < NKEYS + 1; key++) + if (!strcmp(xpmColorKeys[key - 1], str2)) + break; + } else + key = NKEYS + 1; + if (key > NKEYS) { /* append name */ + if (!curkey) + pm_error("error scanning color table", 0, 0, 0, 0, 0); + if (!lastwaskey) + strcat(curbuf, " "); /* append space */ + strcat(curbuf, str2); /* append buf */ + lastwaskey = 0; + } + if (key <= NKEYS) { /* new key */ + if (curkey > highkey) { /* flush string */ + if (*chars_per_pixelP <= 2) + /* Index into table. */ + (*colorsP)[v] = ppm_parsecolor(curbuf, + (pixval) PPM_MAXMAXVAL); + else { + /* Set up linear search table. */ + (*colorsP)[i] = ppm_parsecolor(curbuf, + (pixval) PPM_MAXMAXVAL); + ptab[i] = v; + } + highkey = curkey; + } + curkey = key; /* set new key */ + curbuf[0] = '\0'; /* reset curbuf */ + lastwaskey = 1; + } + if (*t2 == '"') break; + } + if (curkey > highkey) { + if (*chars_per_pixelP <= 2) + /* Index into table. */ + (*colorsP)[v] = ppm_parsecolor(curbuf, + (pixval) PPM_MAXMAXVAL); + else { + /* Set up linear search table. */ + (*colorsP)[i] = ppm_parsecolor(curbuf, + (pixval) PPM_MAXMAXVAL); + ptab[i] = v; + } + highkey = curkey; + } + if (highkey == 1) + pm_error("error scanning color table", 0, 0, 0, 0, 0); + } + /* Read pixels. */ + getline(line, sizeof(line), stream); + /* skip the comment line if any */ + if (!strncmp(line, "/*", 2)) + getline(line, sizeof(line), stream); + + } else { /* try as an XPM version 1 file */ + + /* Read the initial defines. */ + for (;;) { + if (flag) + getline(line, sizeof(line), stream); + else + flag++; + + if (sscanf(line, "#define %s %d", str1, &v) == 2) { + if ((t1 = rindex(str1, '_')) == NULL) + t1 = str1; + else + ++t1; + if (!strcmp(t1, "format")) + format = v; + else if (!strcmp(t1, "width")) + *widthP = v; + else if (!strcmp(t1, "height")) + *heightP = v; + else if (!strcmp(t1, "ncolors")) + *ncolorsP = v; + else if (!strcmp(t1, "pixel")) + *chars_per_pixelP = v; + } else if (!strncmp(line, "static char", 11)) { + if ((t1 = rindex(line, '_')) == NULL) + t1 = line; + else + ++t1; + break; + } + } + if (format == -1) + pm_error("missing or invalid format", 0, 0, 0, 0, 0); + if (format != 1) + pm_error("can't handle XPM version %d", format, 0, 0, 0, 0); + if (*widthP == -1) + pm_error("missing or invalid width", 0, 0, 0, 0, 0); + if (*heightP == -1) + pm_error("missing or invalid height", 0, 0, 0, 0, 0); + if (*ncolorsP == -1) + pm_error("missing or invalid ncolors", 0, 0, 0, 0, 0); + if (*chars_per_pixelP == -1) + pm_error("missing or invalid chars_per_pixel", 0, 0, 0, 0, 0); + if (*chars_per_pixelP > 2) + pm_message("warning, chars_per_pixel > 2 uses a lot of memory" + ,0, 0, 0, 0, 0); + + /* If there's a monochrome color table, skip it. */ + if (!strncmp(t1, "mono", 4)) { + for (;;) { + getline(line, sizeof(line), stream); + if (!strncmp(line, "static char", 11)) + break; + } + } + /* Allocate space for color table. */ + if (*chars_per_pixelP <= 2) { + /* Up to two chars per pixel, we can use an indexed table. */ + v = 1; + for (i = 0; i < *chars_per_pixelP; ++i) + v *= 256; + *colorsP = ppm_allocrow(v); + } else { + /* Over two chars per pixel, we fall back on linear search. */ + *colorsP = ppm_allocrow(*ncolorsP); + ptab = (int *) malloc(*ncolorsP * sizeof(int)); + } + + /* Read color table. */ + for (i = 0; i < *ncolorsP; ++i) { + getline(line, sizeof(line), stream); + + if ((t1 = index(line, '"')) == NULL) + pm_error("error scanning color table", 0, 0, 0, 0, 0); + if ((t2 = index(t1 + 1, '"')) == NULL) + pm_error("error scanning color table", 0, 0, 0, 0, 0); + if (t2 - t1 - 1 != *chars_per_pixelP) + pm_error("wrong number of chars per pixel in color table", + 0, 0, 0, 0, 0); + strncpy(str1, t1 + 1, t2 - t1 - 1); + str1[t2 - t1 - 1] = '\0'; + + if ((t1 = index(t2 + 1, '"')) == NULL) + pm_error("error scanning color table", 0, 0, 0, 0, 0); + if ((t2 = index(t1 + 1, '"')) == NULL) + pm_error("error scanning color table", 0, 0, 0, 0, 0); + strncpy(str2, t1 + 1, t2 - t1 - 1); + str2[t2 - t1 - 1] = '\0'; + + v = 0; + for (j = 0; j < *chars_per_pixelP; ++j) + v = (v << 8) + str1[j]; + if (*chars_per_pixelP <= 2) + /* Index into table. */ + (*colorsP)[v] = ppm_parsecolor(str2, + (pixval) PPM_MAXMAXVAL); + else { + /* Set up linear search table. */ + (*colorsP)[i] = ppm_parsecolor(str2, + (pixval) PPM_MAXMAXVAL); + ptab[i] = v; + } + } + + /* Read pixels. */ + for (;;) { + getline(line, sizeof(line), stream); + if (!strncmp(line, "static char", 11)) + break; + } + } + datasize = *widthP * *heightP; + *dataP = (int *) malloc(datasize * sizeof(int)); + if (*dataP == 0) + pm_error("out of memory", 0, 0, 0, 0, 0); + i = 0; + ptr = *dataP; + for (;;) { + if (flag) + getline(line, sizeof(line), stream); + else + flag++; + + /* Find the open quote. */ + if ((t1 = index(line, '"')) == NULL) + pm_error("error scanning pixels", 0, 0, 0, 0, 0); + ++t1; + + /* Handle pixels until a close quote or the end of the image. */ + while (*t1 != '"') { + v = 0; + for (j = 0; j < *chars_per_pixelP; ++j) + v = (v << 8) + *t1++; + if (*chars_per_pixelP <= 2) + /* Index into table. */ + *ptr++ = v; + else { + /* Linear search into table. */ + for (j = 0; j < *ncolorsP; ++j) + if (ptab[j] == v) + goto gotit; + pm_error("unrecognized pixel in line \"%s\"", line, + 0, 0, 0, 0); + gotit: + *ptr++ = j; + } + ++i; + if (i >= datasize) + return; + } + } +} + + +static void +getline(line, size, stream) + char *line; + int size; + FILE *stream; +{ + if (fgets(line, MAX_LINE, stream) == NULL) + pm_error("EOF / read error", 0, 0, 0, 0, 0); + if (strlen(line) == MAX_LINE - 1) + pm_error("line too long", 0, 0, 0, 0, 0); +} diff --git a/src/xpm/create.c b/src/xpm/create.c new file mode 100644 index 0000000..238a2bb --- /dev/null +++ b/src/xpm/create.c @@ -0,0 +1,963 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* create.c: * +* * +* XPM library * +* Create an X image and possibly its related shape mask * +* from the given xpmInternAttrib. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpmP.h" +#ifdef VMS +#include "sys$library:ctype.h" +#else +#include <ctype.h> +#endif + +LFUNC(xpmVisualType, int, (Visual *visual)); + +LFUNC(SetColor, int, (Display * display, Colormap colormap, char *colorname, + unsigned int color_index, Pixel * image_pixel, + Pixel * mask_pixel, unsigned int * mask_pixel_index, + Pixel ** pixels, unsigned int * npixels, + XpmAttributes *attributes)); + +LFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes, + char ***ct, unsigned int ncolors, Pixel *ip, + Pixel *mp, unsigned int *mask_pixel, Pixel **pixels, + unsigned int *npixels)); + +LFUNC(CreateXImage, int, (Display * display, Visual * visual, + unsigned int depth, unsigned int width, + unsigned int height, XImage ** image_return)); + +LFUNC(SetImagePixels, void, (XImage * image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel * pixels)); + +LFUNC(SetImagePixels32, void, (XImage * image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel * pixels)); + +LFUNC(SetImagePixels16, void, (XImage * image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel * pixels)); + +LFUNC(SetImagePixels8, void, (XImage * image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel * pixels)); + +LFUNC(SetImagePixels1, void, (XImage * image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel * pixels)); + +#ifdef NEED_STRCASECMP + +LFUNC(strcasecmp, int, (char *s1, char *s2)); + +/* + * in case strcasecmp is not provided by the system here is one + * which does the trick + */ +static int +strcasecmp(s1, s2) + register char *s1, *s2; +{ + register int c1, c2; + + while (*s1 && *s2) { + c1 = isupper(*s1) ? tolower(*s1) : *s1; + c2 = isupper(*s2) ? tolower(*s2) : *s2; + if (c1 != c2) + return (1); + s1++; + s2++; + } + if (*s1 || *s2) + return (1); + return (0); +} + +#endif + +/* + * return the default color key related to the given visual + */ +static int +xpmVisualType(visual) + Visual *visual; +{ + switch (visual->class) { + case StaticGray: + case GrayScale: + switch (visual->map_entries) { + case 2: + return (MONO); + case 4: + return (GRAY4); + default: + return (GRAY); + } + default: + return (COLOR); + } +} + +/* + * set the color pixel related to the given colorname, + * return 0 if success, 1 otherwise. + */ + +static int +SetColor(display, colormap, colorname, color_index, + image_pixel, mask_pixel, mask_pixel_index, + pixels, npixels, attributes) + Display *display; + Colormap colormap; + char *colorname; + unsigned int color_index; + Pixel *image_pixel, *mask_pixel; + unsigned int *mask_pixel_index; + Pixel **pixels; + unsigned int *npixels; + XpmAttributes *attributes; +{ + XColor xcolor; + + if (strcasecmp(colorname, TRANSPARENT_COLOR)) { + if (!XParseColor(display, colormap, colorname, &xcolor)) return(1); + else if (!XAllocColor(display, colormap, &xcolor)) + { + if (attributes && (attributes->valuemask & XpmCloseness) && + attributes->closeness != 0) + { + XColor *cols; + unsigned int ncols,i,closepix; + long int closediff,closeness = attributes->closeness; + + if (attributes && attributes->valuemask & XpmDepth) + ncols = 1 << attributes->depth; + else + ncols = 1 << DefaultDepth(display, DefaultScreen(display)); + + cols = (XColor*)calloc(ncols,sizeof(XColor)); + for (i = 0; i < ncols; ++i) cols[i].pixel = i; + XQueryColors(display,colormap,cols,ncols); + + for (i = 0, closediff = 0x7FFFFFFF; i < ncols; ++i) + { +#define COLOR_FACTOR 3 +#define BRIGHTNESS_FACTOR 1 + + long int newclosediff = + COLOR_FACTOR * ( + abs((long)xcolor.red - (long)cols[i].red) + + abs((long)xcolor.green - (long)cols[i].green) + + abs((long)xcolor.blue - (long)cols[i].blue)) + + BRIGHTNESS_FACTOR * abs( + ((long)xcolor.red+(long)xcolor.green+(long)xcolor.blue) - + ((long)cols[i].red+(long)cols[i].green+(long)cols[i].blue)); + + if (newclosediff < closediff) + { closepix = i; closediff = newclosediff; } + } + + if ((long)cols[closepix].red >= (long)xcolor.red - closeness && + (long)cols[closepix].red <= (long)xcolor.red + closeness && + (long)cols[closepix].green >= (long)xcolor.green - closeness && + (long)cols[closepix].green <= (long)xcolor.green + closeness && + (long)cols[closepix].blue >= (long)xcolor.blue - closeness && + (long)cols[closepix].blue <= (long)xcolor.blue + closeness) + { + xcolor = cols[closepix]; free(cols); + if (!XAllocColor(display, colormap, &xcolor)) return (1); + } + else { free(cols); return (1); } + } + else return (1); + } + *image_pixel = xcolor.pixel; + *mask_pixel = 1; + (*pixels)[*npixels] = xcolor.pixel; + (*npixels)++; + } else { + *image_pixel = 0; + *mask_pixel = 0; + *mask_pixel_index = color_index;/* store the color table index */ + } + return (0); +} + +static int +CreateColors(display, attributes, ct, ncolors, + ip, mp, mask_pixel, pixels, npixels) + Display *display; + XpmAttributes *attributes; + char ***ct; + unsigned int ncolors; + Pixel *ip; + Pixel *mp; + unsigned int *mask_pixel; /* mask pixel index */ + Pixel **pixels; /* allocated pixels */ + unsigned int *npixels; /* number of allocated pixels */ +{ + /* variables stored in the XpmAttributes structure */ + Visual *visual; + Colormap colormap; + XpmColorSymbol *colorsymbols; + unsigned int numsymbols; + + char *colorname; + unsigned int a, b, l; + Boolean pixel_defined; + unsigned int key; + XpmColorSymbol *cs; + char **cts; + int ErrorStatus = XpmSuccess; + char *s; + int cts_index; + + /* + * retrieve information from the XpmAttributes + */ + if (attributes && attributes->valuemask & XpmColorSymbols) { + colorsymbols = attributes->colorsymbols; + numsymbols = attributes->numsymbols; + } else + numsymbols = 0; + + if (attributes && attributes->valuemask & XpmVisual) + visual = attributes->visual; + else + visual = DefaultVisual(display, DefaultScreen(display)); + + if (attributes && attributes->valuemask & XpmColormap) + colormap = attributes->colormap; + else + colormap = DefaultColormap(display, DefaultScreen(display)); + + key = xpmVisualType(visual); + switch(key) + { + case MONO: cts_index = 2; break; + case GRAY4: cts_index = 3; break; + case GRAY: cts_index = 4; break; + case COLOR: cts_index = 5; break; + } + + for (a = 0; a < ncolors; a++, ct++, ip++, mp++) { + colorname = NULL; + pixel_defined = False; + cts = *ct; + + /* + * look for a defined symbol + */ + if (numsymbols && cts[1]) { + s = cts[1]; + for (l = 0, cs = colorsymbols; l < numsymbols; l++, cs++) + if ((!cs->name && cs->value && cts[cts_index] && + !strcasecmp(cs->value,cts[cts_index])) || + cs->name && !strcmp(cs->name, s)) + break; + if (l != numsymbols) { + if (cs->name && cs->value) + colorname = cs->value; + else + pixel_defined = True; + } + } + if (!pixel_defined) { /* pixel not given as symbol value */ + if (colorname) { /* colorname given as symbol value */ + if (!SetColor(display, colormap, colorname, a, ip, mp, + mask_pixel, pixels, npixels, attributes)) + pixel_defined = True; + else + ErrorStatus = XpmColorError; + } + b = key; + while (!pixel_defined && b > 1) { + if (cts[b]) { + if (!SetColor(display, colormap, cts[b], a, ip, mp, + mask_pixel, pixels, npixels, attributes)) { + pixel_defined = True; + break; + } else + ErrorStatus = XpmColorError; + } + b--; + } + b = key + 1; + while (!pixel_defined && b < NKEYS + 1) { + if (cts[b]) { + if (!SetColor(display, colormap, cts[b], a, ip, mp, + mask_pixel, pixels, npixels, attributes)) { + pixel_defined = True; + break; + } else + ErrorStatus = XpmColorError; + } + b++; + } + if (!pixel_defined) + return (XpmColorFailed); + } else { + *ip = colorsymbols[l].pixel; + *mp = 1; + } + } + return (ErrorStatus); +} + +/* function call in case of error, frees only locally allocated variables */ +#undef RETURN +#ifdef Debug +/* + * XDestroyImage free the image data but mnemosyne don't know about it + * so I free them by hand to avoid mnemalyse report it as lost data. + */ +#define RETURN(status) \ + { if (image) { \ + free(image->data); \ + XDestroyImage(image); } \ + if (shapeimage) { \ + free(shapeimage->data); \ + XDestroyImage(shapeimage); } \ + if (image_pixels) free(image_pixels); \ + if (mask_pixels) free(mask_pixels); \ + if (npixels) XFreeColors(display, colormap, pixels, npixels, 0); \ + if (pixels) free(pixels); \ + return (status); } + +#else + +#define RETURN(status) \ + { if (image) XDestroyImage(image); \ + if (shapeimage) XDestroyImage(shapeimage); \ + if (image_pixels) free(image_pixels); \ + if (mask_pixels) free(mask_pixels); \ + if (npixels) XFreeColors(display, colormap, pixels, npixels, 0); \ + if (pixels) free(pixels); \ + return (status); } + +#endif + +xpmCreateImage(display, attrib, image_return, shapeimage_return, attributes) + Display *display; + xpmInternAttrib *attrib; + XImage **image_return; + XImage **shapeimage_return; + XpmAttributes *attributes; +{ + /* variables stored in the XpmAttributes structure */ + Visual *visual; + Colormap colormap; + unsigned int depth; + + /* variables to return */ + XImage *image = NULL; + XImage *shapeimage = NULL; + unsigned int mask_pixel; + int ErrorStatus; + + /* calculation variables */ + Pixel *image_pixels = NULL; + Pixel *mask_pixels = NULL; + Pixel *pixels = NULL; /* allocated pixels */ + unsigned int npixels = 0; /* number of allocated pixels */ + + /* + * retrieve information from the XpmAttributes + */ + if (attributes && attributes->valuemask & XpmVisual) + visual = attributes->visual; + else + visual = DefaultVisual(display, DefaultScreen(display)); + + if (attributes && attributes->valuemask & XpmColormap) + colormap = attributes->colormap; + else + colormap = DefaultColormap(display, DefaultScreen(display)); + + if (attributes && attributes->valuemask & XpmDepth) + depth = attributes->depth; + else + depth = DefaultDepth(display, DefaultScreen(display)); + + ErrorStatus = XpmSuccess; + + /* + * malloc pixels index tables + */ + + image_pixels = (Pixel *) malloc(sizeof(Pixel) * attrib->ncolors); + if (!image_pixels) + return(XpmNoMemory); + + mask_pixels = (Pixel *) malloc(sizeof(Pixel) * attrib->ncolors); + if (!mask_pixels) + RETURN(ErrorStatus); + + mask_pixel = UNDEF_PIXEL; + + /* maximum of allocated pixels will be the number of colors */ + pixels = (Pixel *) malloc(sizeof(Pixel) * attrib->ncolors); + if (!pixels) + RETURN(ErrorStatus); + + /* + * get pixel colors, store them in index tables + */ + + ErrorStatus = CreateColors(display, attributes, attrib->colorTable, + attrib->ncolors, image_pixels, mask_pixels, + &mask_pixel, &pixels, &npixels); + if (ErrorStatus != XpmSuccess && (ErrorStatus < 0 || attributes && + (attributes->valuemask & XpmExactColors) && attributes->exactColors)) + RETURN(ErrorStatus); + + /* + * create the image + */ + if (image_return) { + ErrorStatus = CreateXImage(display, visual, depth, + attrib->width, attrib->height, &image); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + /* + * set the image data + * + * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use + * optimized functions, otherwise use slower but sure general one. + * + */ + + if (image->depth == 1) + SetImagePixels1(image, attrib->width, attrib->height, + attrib->pixelindex, image_pixels); + else if (image->bits_per_pixel == 8) + SetImagePixels8(image, attrib->width, attrib->height, + attrib->pixelindex, image_pixels); + else if (image->bits_per_pixel == 16) + SetImagePixels16(image, attrib->width, attrib->height, + attrib->pixelindex, image_pixels); + else if (image->bits_per_pixel == 32) + SetImagePixels32(image, attrib->width, attrib->height, + attrib->pixelindex, image_pixels); + else + SetImagePixels(image, attrib->width, attrib->height, + attrib->pixelindex, image_pixels); + } + + /* + * create the shape mask image + */ + if (mask_pixel != UNDEF_PIXEL && shapeimage_return) { + ErrorStatus = CreateXImage(display, visual, 1, attrib->width, + attrib->height, &shapeimage); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + SetImagePixels1(shapeimage, attrib->width, attrib->height, + attrib->pixelindex, mask_pixels); + } + free(mask_pixels); + free(pixels); + + /* + * if requested store used pixels in the XpmAttributes structure + */ + if (attributes && + (attributes->valuemask & XpmReturnInfos + || attributes->valuemask & XpmReturnPixels)) { + if (mask_pixel != UNDEF_PIXEL) { + Pixel *pixels, *p1, *p2; + unsigned int a; + + attributes->npixels = attrib->ncolors - 1; + pixels = (Pixel *) malloc(sizeof(Pixel) * attributes->npixels); + if (pixels) { + p1 = image_pixels; + p2 = pixels; + for (a = 0; a < attrib->ncolors; a++, p1++) + if (a != mask_pixel) + *p2++ = *p1; + attributes->pixels = pixels; + } else { + /* if error just say we can't return requested data */ + attributes->valuemask &= ~XpmReturnPixels; + attributes->valuemask &= ~XpmReturnInfos; + attributes->pixels = NULL; + attributes->npixels = 0; + } + free(image_pixels); + } else { + attributes->pixels = image_pixels; + attributes->npixels = attrib->ncolors; + } + attributes->mask_pixel = mask_pixel; + } else + free(image_pixels); + + + /* + * return created images + */ + if (image_return) + *image_return = image; + + if (shapeimage_return) + *shapeimage_return = shapeimage; + + return (ErrorStatus); +} + + +/* + * Create an XImage + */ +static int +CreateXImage(display, visual, depth, width, height, image_return) + Display *display; + Visual *visual; + unsigned int depth; + unsigned int width; + unsigned int height; + XImage **image_return; +{ + int bitmap_pad; + + /* first get bitmap_pad */ + if (depth > 16) + bitmap_pad = 32; + else if (depth > 8) + bitmap_pad = 16; + else + bitmap_pad = 8; + + /* then create the XImage with data = NULL and bytes_per_line = 0 */ + + *image_return = XCreateImage(display, visual, depth, ZPixmap, 0, 0, + width, height, bitmap_pad, 0); + if (!*image_return) + return (XpmNoMemory); + + /* now that bytes_per_line must have been set properly alloc data */ + + (*image_return)->data = + (char *) malloc((*image_return)->bytes_per_line * height); + + if (!(*image_return)->data) { + XDestroyImage(*image_return); + *image_return = NULL; + return (XpmNoMemory); + } + return (XpmSuccess); +} + + +/* + * The functions below are written from X11R5 MIT's code (XImUtil.c) + * + * The idea is to have faster functions than the standard XPutPixel function + * to build the image data. Indeed we can speed up things by suppressing tests + * performed for each pixel. We do the same tests but at the image level. + * We also assume that we use only ZPixmap images with null offsets. + */ + +LFUNC(_putbits, void, (register char *src, int dstoffset, + register int numbits, register char *dst)); + +LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register int nb)); + +static unsigned char Const _reverse_byte[0x100] = { + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff +}; + +static int +_XReverse_Bytes(bpt, nb) + register unsigned char *bpt; + register int nb; +{ + do { + *bpt = _reverse_byte[*bpt]; + bpt++; + } while (--nb > 0); + return 0; +} + + +void +xpm_xynormalizeimagebits(bp, img) + register unsigned char *bp; + register XImage *img; +{ + register unsigned char c; + + if (img->byte_order != img->bitmap_bit_order) { + switch (img->bitmap_unit) { + + case 16: + c = *bp; + *bp = *(bp + 1); + *(bp + 1) = c; + break; + + case 32: + c = *(bp + 3); + *(bp + 3) = *bp; + *bp = c; + c = *(bp + 2); + *(bp + 2) = *(bp + 1); + *(bp + 1) = c; + break; + } + } + if (img->bitmap_bit_order == MSBFirst) + _XReverse_Bytes(bp, img->bitmap_unit >> 3); +} + +void +xpm_znormalizeimagebits(bp, img) + register unsigned char *bp; + register XImage *img; +{ + register unsigned char c; + + switch (img->bits_per_pixel) { + + case 4: + *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF); + break; + + case 16: + c = *bp; + *bp = *(bp + 1); + *(bp + 1) = c; + break; + + case 24: + c = *(bp + 2); + *(bp + 2) = *bp; + *bp = c; + break; + + case 32: + c = *(bp + 3); + *(bp + 3) = *bp; + *bp = c; + c = *(bp + 2); + *(bp + 2) = *(bp + 1); + *(bp + 1) = c; + break; + } +} + +static unsigned char Const _lomask[0x09] = { + 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; +static unsigned char Const _himask[0x09] = { + 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00}; + +static void +_putbits(src, dstoffset, numbits, dst) + register char *src; /* address of source bit string */ + int dstoffset; /* bit offset into destination; + * range is 0-31 */ + register int numbits; /* number of bits to copy to + * destination */ + register char *dst; /* address of destination bit string */ +{ + register unsigned char chlo, chhi; + int hibits; + + dst = dst + (dstoffset >> 3); + dstoffset = dstoffset & 7; + hibits = 8 - dstoffset; + chlo = *dst & _lomask[dstoffset]; + for (;;) { + chhi = (*src << dstoffset) & _himask[dstoffset]; + if (numbits <= hibits) { + chhi = chhi & _lomask[dstoffset + numbits]; + *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi; + break; + } + *dst = chhi | chlo; + dst++; + numbits = numbits - hibits; + chlo = (unsigned char) (*src & _himask[hibits]) >> hibits; + src++; + if (numbits <= dstoffset) { + chlo = chlo & _lomask[numbits]; + *dst = (*dst & _himask[numbits]) | chlo; + break; + } + numbits = numbits - dstoffset; + } +} + +/* + * Default method to write pixels into a Z image data structure. + * The algorithm used is: + * + * copy the destination bitmap_unit or Zpixel to temp + * normalize temp if needed + * copy the pixel bits into the temp + * renormalize temp if needed + * copy the temp back into the destination image data + */ + +static void +SetImagePixels(image, width, height, pixelindex, pixels) + XImage *image; + unsigned int width; + unsigned int height; + unsigned int *pixelindex; + Pixel *pixels; +{ + register char *src; + register char *dst; + register unsigned int *iptr; + register int x, y, i; + register char *data; + Pixel pixel, px; + int nbytes, depth, ibu, ibpp; + + data = image->data; + iptr = pixelindex; + depth = image->depth; + if (image->depth == 1) { + ibu = image->bitmap_unit; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + pixel = pixels[*iptr]; + for (i = 0, px = pixel; + i < sizeof(unsigned long); i++, px >>= 8) + ((unsigned char *) &pixel)[i] = px; + src = &data[XYINDEX(x, y, image)]; + dst = (char *) &px; + px = 0; + nbytes = ibu >> 3; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + XYNORMALIZE(&px, image); + _putbits((char *) &pixel, (x % ibu), 1, (char *) &px); + XYNORMALIZE(&px, image); + src = (char *) &px; + dst = &data[XYINDEX(x, y, image)]; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + } + } else { + ibpp = image->bits_per_pixel; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + pixel = pixels[*iptr]; + if (depth == 4) + pixel &= 0xf; + for (i = 0, px = pixel; + i < sizeof(unsigned long); i++, px >>= 8) + ((unsigned char *) &pixel)[i] = px; + src = &data[ZINDEX(x, y, image)]; + dst = (char *) &px; + px = 0; + nbytes = (ibpp + 7) >> 3; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + ZNORMALIZE(&px, image); + _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px); + ZNORMALIZE(&px, image); + src = (char *) &px; + dst = &data[ZINDEX(x, y, image)]; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + } + } +} + +/* + * write pixels into a 32-bits Z image data structure + */ + +#ifndef WORD64 +static unsigned long byteorderpixel = MSBFirst << 24; + +#endif + +static void +SetImagePixels32(image, width, height, pixelindex, pixels) + XImage *image; + unsigned int width; + unsigned int height; + unsigned int *pixelindex; + Pixel *pixels; +{ + register unsigned char *addr; + register unsigned char *data; + register unsigned int *iptr; + register int x, y; + Pixel pixel; + + data = (unsigned char *) image->data; + iptr = pixelindex; +#ifndef WORD64 + if (*((char *) &byteorderpixel) == image->byte_order) { + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + *((unsigned long *)addr) = pixels[*iptr]; + } + } else +#endif + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + pixel = pixels[*iptr]; + addr[0] = pixel >> 24; + addr[1] = pixel >> 16; + addr[2] = pixel >> 8; + addr[3] = pixel; + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + pixel = pixels[*iptr]; + addr[0] = pixel; + addr[1] = pixel >> 8; + addr[2] = pixel >> 16; + addr[3] = pixel >> 24; + } +} + +/* + * write pixels into a 16-bits Z image data structure + */ + +static void +SetImagePixels16(image, width, height, pixelindex, pixels) + XImage *image; + unsigned int width; + unsigned int height; + unsigned int *pixelindex; + Pixel *pixels; +{ + register unsigned char *addr; + register unsigned char *data; + register unsigned int *iptr; + register int x, y; + + data = (unsigned char *) image->data; + iptr = pixelindex; + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX16(x, y, image)]; + addr[0] = pixels[*iptr] >> 8; + addr[1] = pixels[*iptr]; + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX16(x, y, image)]; + addr[0] = pixels[*iptr]; + addr[1] = pixels[*iptr] >> 8; + } +} + +/* + * write pixels into a 8-bits Z image data structure + */ + +static void +SetImagePixels8(image, width, height, pixelindex, pixels) + XImage *image; + unsigned int width; + unsigned int height; + unsigned int *pixelindex; + Pixel *pixels; +{ + register char *data; + register unsigned int *iptr; + register int x, y; + + data = image->data; + iptr = pixelindex; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) + data[ZINDEX8(x, y, image)] = pixels[*iptr]; +} + +/* + * write pixels into a 1-bit depth image data structure and **offset null** + */ + +static void +SetImagePixels1(image, width, height, pixelindex, pixels) + XImage *image; + unsigned int width; + unsigned int height; + unsigned int *pixelindex; + Pixel *pixels; +{ + register unsigned int *iptr; + register int x, y; + register char *data; + + if (image->byte_order != image->bitmap_bit_order) + SetImagePixels(image, width, height, pixelindex, pixels); + else { + data = image->data; + iptr = pixelindex; + if (image->bitmap_bit_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + if (pixels[*iptr] & 1) + data[ZINDEX1(x, y, image)] |= 0x80 >> (x & 7); + else + data[ZINDEX1(x, y, image)] &= ~(0x80 >> (x & 7)); + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + if (pixels[*iptr] & 1) + data[ZINDEX1(x, y, image)] |= 1 << (x & 7); + else + data[ZINDEX1(x, y, image)] &= ~(1 << (x & 7)); + } + } +} diff --git a/src/xpm/data.c b/src/xpm/data.c new file mode 100644 index 0000000..87901d9 --- /dev/null +++ b/src/xpm/data.c @@ -0,0 +1,422 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* data.c: * +* * +* XPM library * +* IO utilities * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* Official version number */ +static char *RCS_Version = "$XpmVersion: 3.2c $"; + +/* Internal version number */ +static char *RCS_Id = "$Id: xpm.shar,v 3.13 1992/12/29 16:05:26 lehors Exp $"; + +#include "xpmP.h" +#ifdef VMS +#include "sys$library:stat.h" +#include "sys$library:ctype.h" +#else +#include <sys/stat.h> +#include <ctype.h> +#endif + +FUNC(atoui, unsigned int, (char *p, unsigned int l, unsigned int *ui_return)); +LFUNC(ParseComment, int, (xpmData *mdata)); + +unsigned int +atoui(p, l, ui_return) + register char *p; + unsigned int l; + unsigned int *ui_return; +{ + register int n, i; + + n = 0; + for (i = 0; i < l; i++) + if (*p >= '0' && *p <= '9') + n = n * 10 + *p++ - '0'; + else + break; + + if (i != 0 && i == l) { + *ui_return = n; + return 1; + } else + return 0; +} + +static int +ParseComment(mdata) + xpmData *mdata; +{ + FILE *file = mdata->stream.file; + register int c; + register unsigned int n = 0, a; + unsigned int notend; + char *s, *s2; + + s = mdata->Comment; + *s = mdata->Bcmt[0]; + + /* skip the string beginning comment */ + s2 = mdata->Bcmt; + do { + c = getc(file); + *++s = c; + n++; + s2++; + } while (c == *s2 && *s2 != '\0' + && c != EOF && c != mdata->Bos); + + if (*s2 != '\0') { + /* this wasn't the beginning of a comment */ + /* put characters back in the order that we got them */ + for (a = n; a > 0; a--, s--) + ungetc(*s, file); + return 0; + } + + /* store comment */ + mdata->Comment[0] = *s; + s = mdata->Comment; + notend = 1; + n = 0; + while (notend) { + s2 = mdata->Ecmt; + while (*s != *s2 && c != EOF && c != mdata->Bos) { + c = getc(file); + *++s = c; + n++; + } + mdata->CommentLength = n; + do { + c = getc(file); + n++; + *++s = c; + s2++; + } while (c == *s2 && *s2 != '\0' + && c != EOF && c != mdata->Bos); + if (*s2 == '\0') { + /* this is the end of the comment */ + notend = 0; + ungetc(*s, file); + } + } +} + +/* + * skip to the end of the current string and the beginning of the next one + */ +xpmNextString(mdata) + xpmData *mdata; +{ + if (!mdata->type) + mdata->cptr = (mdata->stream.data)[++mdata->line]; + else { + register int c; + FILE *file = mdata->stream.file; + + /* get to the end of the current string */ + if (mdata->Eos) + while ((c = getc(file)) != mdata->Eos && c != EOF); + + /* then get to the beginning of the next string + * looking for possible comment */ + if (mdata->Bos) { + while ((c = getc(file)) != mdata->Bos && c != EOF) + if (mdata->Bcmt && c == mdata->Bcmt[0]) + ParseComment(mdata); + + } else { /* XPM2 natural */ + while (mdata->Bcmt && (c = getc(file)) == mdata->Bcmt[0]) + ParseComment(mdata); + ungetc(c, file); + } + } +} + + +/* + * skip whitespace and compute the following unsigned int, + * returns 1 if one is found and 0 if not + */ +int +xpmNextUI(mdata, ui_return) + xpmData *mdata; + unsigned int *ui_return; +{ + char buf[BUFSIZ]; + int l; + + l = xpmNextWord(mdata, buf); + return atoui(buf, l, ui_return); +} + +/* + * skip whitespace and return the following word + */ +unsigned int +xpmNextWord(mdata, buf) + xpmData *mdata; + char *buf; +{ + register unsigned int n = 0; + int c; + + if (!mdata->type) { + while (isspace(c = *mdata->cptr) && c != mdata->Eos) + mdata->cptr++; + do { + c = *mdata->cptr++; + *buf++ = c; + n++; + } while (!isspace(c) && c != mdata->Eos); + n--; + mdata->cptr--; + } else { + FILE *file = mdata->stream.file; + while (isspace(c = getc(file)) && c != mdata->Eos); + while (!isspace(c) && c != mdata->Eos && c != EOF) { + *buf++ = c; + n++; + c = getc(file); + } + ungetc(c, file); + } + return (n); +} + +/* + * return end of string - WARNING: malloc! + */ +int +xpmGetString(mdata, sptr, l) + xpmData *mdata; + char **sptr; + unsigned int *l; +{ + unsigned int i, n = 0; + int c; + char *p, *q, buf[BUFSIZ]; + + if (!mdata->type) { + if (mdata->cptr) { + char *start; + while (isspace(c = *mdata->cptr) && c != mdata->Eos) + mdata->cptr++; + start = mdata->cptr; + while (c = *mdata->cptr) + mdata->cptr++; + n = mdata->cptr - start + 1; + p = (char *) malloc(n); + if (!p) + return (XpmNoMemory); + strncpy(p, start, n); + } + } else { + FILE *file = mdata->stream.file; + while (isspace(c = getc(file)) && c != mdata->Eos); + if (c == EOF) + return (XpmFileInvalid); + p = NULL; + i = 0; + q = buf; + p = (char *) malloc(1); + while (c != mdata->Eos && c != EOF) { + if (i == BUFSIZ) { + /* get to the end of the buffer */ + /* malloc needed memory */ + q = (char *) realloc(p, n + i); + if (!q) { + free(p); + return (XpmNoMemory); + } + p = q; + q += n; + /* and copy what we already have */ + strncpy(q, buf, i); + n += i; + i = 0; + q = buf; + } + *q++ = c; + i++; + c = getc(file); + } + if (c == EOF) { + free(p); + return (XpmFileInvalid); + } + if (n + i != 0) { + /* malloc needed memory */ + q = (char *) realloc(p, n + i + 1); + if (!q) { + free(p); + return (XpmNoMemory); + } + p = q; + q += n; + /* and copy the buffer */ + strncpy(q, buf, i); + n += i; + p[n++] = '\0'; + } else { + *p = '\0'; + n = 1; + } + ungetc(c, file); + } + *sptr = p; + *l = n; + return (XpmSuccess); +} + +/* + * get the current comment line + */ +xpmGetCmt(mdata, cmt) + xpmData *mdata; + char **cmt; +{ + if (!mdata->type) + *cmt = NULL; + else + if (mdata->CommentLength) { + *cmt = (char *) malloc(mdata->CommentLength + 1); + strncpy(*cmt, mdata->Comment, mdata->CommentLength); + (*cmt)[mdata->CommentLength] = '\0'; + mdata->CommentLength = 0; + } else + *cmt = NULL; +} + +/* + * open the given file to be read as an xpmData which is returned. + */ +int +xpmReadFile(filename, mdata) + char *filename; + xpmData *mdata; +{ + char *compressfile, buf[BUFSIZ]; + struct stat status; + + if (!filename) { + mdata->stream.file = (stdin); + mdata->type = XPMFILE; + } else { +#ifdef ZPIPE + if (((int)strlen(filename) > 2) && + !strcmp(".Z", filename + (strlen(filename) - 2))) { + mdata->type = XPMPIPE; + sprintf(buf, "uncompress -c %s", filename); + if (!(mdata->stream.file = popen(buf, "r"))) + return (XpmOpenFailed); + + } else { + if (!(compressfile = (char *) malloc(strlen(filename) + 3))) + return (XpmNoMemory); + + strcpy(compressfile, filename); + strcat(compressfile, ".Z"); + if (!stat(compressfile, &status)) { + sprintf(buf, "uncompress -c %s", compressfile); + if (!(mdata->stream.file = popen(buf, "r"))) { + free(compressfile); + return (XpmOpenFailed); + } + mdata->type = XPMPIPE; + } else { +#endif + if (!(mdata->stream.file = fopen(filename, "r"))) { +#ifdef ZPIPE + free(compressfile); +#endif + return (XpmOpenFailed); + } + mdata->type = XPMFILE; +#ifdef ZPIPE + } + free(compressfile); + } +#endif + } + mdata->CommentLength = 0; + return (XpmSuccess); +} + +/* + * open the given file to be written as an xpmData which is returned + */ +int +xpmWriteFile(filename, mdata) + char *filename; + xpmData *mdata; +{ + char buf[BUFSIZ]; + + if (!filename) { + mdata->stream.file = (stdout); + mdata->type = XPMFILE; + } else { +#ifdef ZPIPE + if ((int)strlen(filename) > 2 + && !strcmp(".Z", filename + ((int)strlen(filename) - 2))) { + sprintf(buf, "compress > %s", filename); + if (!(mdata->stream.file = popen(buf, "w"))) + return (XpmOpenFailed); + + mdata->type = XPMPIPE; + } else { +#endif + if (!(mdata->stream.file = fopen(filename, "w"))) + return (XpmOpenFailed); + + mdata->type = XPMFILE; +#ifdef ZPIPE + } +#endif + } + return (XpmSuccess); +} + +/* + * open the given array to be read or written as an xpmData which is returned + */ +void +xpmOpenArray(data, mdata) + char **data; + xpmData *mdata; +{ + mdata->type = XPMARRAY; + mdata->stream.data = data; + mdata->cptr = *data; + mdata->line = 0; + mdata->CommentLength = 0; + mdata->Bcmt = mdata->Ecmt = NULL; + mdata->Bos = mdata->Eos = '\0'; +} + +/* + * close the file related to the xpmData if any + */ +XpmDataClose(mdata) + xpmData *mdata; +{ + switch (mdata->type) { + case XPMARRAY: + break; + case XPMFILE: + if (mdata->stream.file != (stdout) && mdata->stream.file != (stdin)) + fclose(mdata->stream.file); + break; +#ifdef ZPIPE + case XPMPIPE: + pclose(mdata->stream.file); + break; +#endif + } +} diff --git a/src/xpm/doc/CHANGES b/src/xpm/doc/CHANGES new file mode 100644 index 0000000..22f28a5 --- /dev/null +++ b/src/xpm/doc/CHANGES @@ -0,0 +1,422 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/**************************************************************************\ +* * +* HISTORY of user-visible changes * +* * +\**************************************************************************/ + +3.2c (92/12/29) + + ENHANCEMENTS: + - parsing optimized for single and double characters color + - patch originally from Martin Brunecky + marbru@build1.auto-trol.com + + BUGS CORRECTED: + - XpmFreeExtensions was calling free on some argument without checking + it was not NULL. + - strdup was not correctly defined for systems which do not provide + it. - Hans-Peter Lichtin <lich@zellweger.ch> + - some bug in XpmCrDataFI.c + - Sven Delmas garfield@avalanche.cs.tu-berlin.de + + NOTE: + - there is still a bug with the creation of the clipmask on display of + depth 2 but I can't find a fix because unfortunately I don't have such + a rendering system and nobody gets the time to investigate for me. + +3.2b (92/10/19) + + ENHANCEMENTS: + - Create XpmReadFileToData and XpmWriteFileFromData + - Dan Greening <dgreen@sti.com> + - added "close colors" support and ability to redefine color values + as pixels at load time, as well as color names + - Jason Patterson <jasonp@fitmail.qut.edu.au> + - errors while parsing or allocating colors now revert to other + visual defaults, creating pixmap/image as expected, and returning + XpmSuccess. The old behaviour of XpmColorError being returned and no + pixmap/image being created can be retained by setting the + exactColors attribute. + - Jason Patterson <jasonp@fitmail.qut.edu.au> + + BUGS CORRECTED: + - SVR4 defines for including <string.h> instead of <strings.h> + - Jason Patterson <jasonp@fitmail.qut.edu.au> + - attributes->extensions and attributes->nextensions fields were not + set correctly when no extensions present in file. + - Simon_Scott Cornish <cornish@ecr.mu.oz.au> + +3.2a (92/08/17) + + ENHANCEMENTS: + - use the mock lisp hashing function instead of the gnu emacs one, + it is faster in some cases and never slower (I've not found any case). + + BUGS CORRECTED: + - function prototypes for ansi compilers. + - some memory initialization bugs (purify is just great for this). + - empty strings in extensions are now correctly handled. + +3.2 (92/07/06) + + NEW FEATURES: + - both format and functions handle extensions data. This allow people + to store additional data related to a pixmap. See documentation for + detail. + - sxpm supports the new option '-c' to use a private colormap. This is + useful when displaying pixmaps using a lot of colors. + - sxpm supports the new option '-v' (verbose) to get possible + extensions print out on standard error. + + ENHANCEMENTS: + - most of the code has been reworked to be improved and thus almost + every function is faster. It takes less than 6 seconds of real time on + a sun4 to display, with sxpm, a 487x635 pixmap using 213 colors, while + it takes 32 seconds with the old library! It takes 18 seconds to + display a 1279x1023 screen dump using 14 colors while xwud takes 10 + seconds. + Of course performance improvements are not always that great, they + depend on the size and number of colors but I'm sure everybody will + appreciate ;-) + I know how to improve it more but this will require changes in the + architecture so this is not for now. Some optimizations have been + contributed by gregor@kafka.saic.com (gregg hanna) and + jnc@csl.biosci.arizona.edu (John N. Calley). + - the Imakefile is modified to let you install sxpm - Rainer Klute + <klute@irb.informatik.uni-dortmund.de> + - xpmP.h declares popen for Sequent platforms - Clinton Jeffery + <cjeffery@cs.arizona.edu> + - XpmWriteFileFromImage/Pixmap rather than truncating the pixmap name + to the first dot changes dots to underscores to get a valid C syntax + name. + + + BUGS CORRECTED: + - there was a bug in the image creation function for some 24 bits + displays. It is fixed. + - allocated color pixels are now freed when an error occurs - + nusser@dec1.wu-wien.ac.at (Stefan Nusser) + + CHANGES TO THE DOC: + - the documentation describes the new XpmExtension structure and how + to use it with read and write functions. + +3.1 (92/02/03) + + ENHANCEMENTS: + - sxpm now have more standard options (mainly suggested by + Rainer Sinkwitz <sinkwitz@ifi.unizh.ch>): + + Usage: sxpm [options...] + Where options are: + + [-d host:display] Display to connect to. + [-g geom] Geometry of window. + [-hints] Set ResizeInc for window. + [-icon filename] Set pixmap for iconWindow. + [-s symbol_name color_name] Overwrite color defaults. + [-p symbol_name pixel_value] Overwrite color defaults. + [-plaid] Read the included plaid pixmap. + [filename] Read from file 'filename', and from + standard input if 'filename' is '-'. + [-o filename] Write to file 'filename', and to standard + output if 'filename' is '-'. + [-nod] Don't display in window. + [-rgb filename] Search color names in the rgb text file + 'filename'. + + if no input is specified sxpm reads from stdandard input. + + + - Xpm functions and Ppm converters now deal with multiword colornames. + patches from Rainer Sinkwitz <sinkwitz@ifi.unizh.ch>. + + +3.0 (91/10/03) + + Functions name and defines have been modified again (sorry for that) + as follows: + + XpmReadPixmapFile XpmReadFileToPixmap + XpmWritePixmapFile XpmWriteFileFromPixmap + + XpmPixmapColorError XpmColorError + XpmPixmapSuccess XpmSuccess + XpmPixmapOpenFailed XpmOpenFailed + XpmPixmapFileInvalid XpmFileInvalid + XpmPixmapNoMemory XpmNoMemory + XpmPixmapColorFailed XpmColorFailed + + To update code using Xpm you can use the included shell script called + rename with the sed commands files name-3.0b-3.0c and name-3.0c-3.0. + Old names still valid though. + + NEW FEATURES: + - four new functions to work with images instead of pixmaps: + + XpmReadFileToImage + XpmWriteFileFromImage + XpmCreateImageFromData + XpmCreateDataFromImage + + ENHANCEMENTS: + Algorithms to create and scan images and pixmaps are based on the + MIT's R5 code, thus they are much cleaner than old ones and should + avoid any problem with any visual (yes, I trust MIT folks :-) + + BUGS CORRECTED: + Imakefile use INCDIR instead of ROOTDIR. + + CHANGES TO THE DOC: + - the documentation presents the four new functions. + +3.0c (91/09/18) + + In answer to request of people functions, types and defines names have + been changed as follows: + + XCreatePixmapFromData XpmCreatePixmapFromData + XCreateDataFromPixmap XpmCreateDataFromPixmap + XReadPixmapFile XpmReadPixmapFile + XWritePixmapFile XpmWritePixmapFile + XFreeXpmAttributes XpmFreeAttributes + + PixmapColorError XpmPixmapColorError + PixmapSuccess XpmPixmapSuccess + PixmapOpenFailed XpmPixmapOpenFailed + PixmapFileInvalid XpmPixmapFileInvalid + PixmapNoMemory XpmPixmapNoMemory + PixmapColorFailed XpmPixmapColorFailed + + ColorSymbol XpmColorSymbol + + Generally speaking every public name begins with 'Xpm' and every + private one with 'xpm'. This should avoid any possible conflict. + + Some files have also be renamed accordingly. + + NEW FEATURES: + - support for VMS and two new options for sxpm: icon and hints (see + manual for details) Richard Hess <rhess%pleione%cimshop@uunet.UU.NET> + - DEFINES in Imakefile and Makefile.noXtree allows you to set the + following: + + ZPIPE for un/compressing piped feature (default is on) + NEED_STRCASECMP for system which doesn't provide one (default + is off) + + - xpmtoppm.c has is own strstr function which is used if NEED_STRSTR + is defined when compiling - Hugues.Leroy@irisa.fr (Hugues Leroy). + + BUGS CORRECTED: + - many bugs have been fixed, especially for ansi compilers - + Doyle C. Davidson (doyle@doyled.b23b.ingr.com) and + Clifford D. Morrison (cdm%bigdaddy%edsr@uunet.UU.NET) + - parser is again a little more improved + +3.0b (91/09/12) + + This is a complete new version with a new API and where files and + structures have been renamed. So this should be taken as a new + starting release. + This release should be quickly followed by the 3.0 because I'm planning + to send it for X11R5 contrib which ends October 5th. + + NEW FEATURES: + - support for transparent color. + - support for hotspot. + - a new function: XCreateDataFromPixmap to create an XPM data from a + pixmap in order to be able to create a new pixmap from this data using + the XCreatePixmapFromData function later on. + - a new structure: XpmAttributes which replace the XpmInfo structure + and which leads to a much simpler API with less arguments. + - arguments such as visual, colormap and depth are optionnal, default + values are taken if omitted. + - parsing and allocating color failures don't simply break anymore. If + another default color can be found it is used and a PixmapColorError + is returned. In case no color can be found then it breaks and returns + PixmapColorFailed. + - for this reason the ErrorStatus codes are redefined as follows: + + null if full success + positive if partial success + negative if failure + + with: + #define PixmapColorError 1 + #define PixmapSuccess 0 + #define PixmapOpenFailed -1 + #define PixmapFileInvalid -2 + #define PixmapNoMemory -3 + #define PixmapColorFailed -4 + + - sxpm prints out a warning when a requested color could not be parsed + or alloc'ed, and an error when none has been found. + - sxpm handles pixmap with transparent color. For this purpose the + plaid_mask.xpm is added to the distribution. + + BUGS CORRECTED: + - I've again improved the memory management. + - the parser is also improved. + - when writting a pixmap to a file the variable name could be + "plaid.xpm" which is not valid in C. Now the extension name is cut off + to give "plaid" as variable name. + - reading multiple words colornames such as "peach puff" where leading + to non readable Xpm files. They are now skipped to have only single + word colorname. Lionel Mallet (mallet@ipvpel.unipv.it). + - parser was triggered by the "/" character inside string. + Doyle C. Davidson (doyle@doyled.b23b.ingr.com). This is corrected. + - sxpm maps the window only if the option "-nod" is not selected. + + CHANGES TO THE DOC: + - the documentation presents the new API and features. + +3.0a (91/04/10) + + This is an alpha version because it supports the new version of XPM, + but the library interface is still the same. Indeed it will change in + future release to get rid of obsolete stuff such as the type argument + of the XWritePixmapFile function. + + ******************************* WARNING ********************************* + The format is not anymore XPM2, it is XPM version 3 which is XPM2 + limited to the C syntax with the key word "XPM" in place of "XPM2 C". + The interface library has not changed yet but the type argument of + XWritePixmapFile and the type member of XpmInfo are not used anymore. + Meanwhile the library which is now called libXpm.a is backward + compatible as XPM2 files can be read. But the XWritePixmapFile + function only writes out XPM version 3 files. + ************************************************************************* + + NEW FEATURES: + - the library doesn't use global variables anymore, thus it should be + able to share it. + - sxpm has been rewritten on top of Xt, it can be used to convert + files from XPM2 to XPM version 3. + - xpm1to2c.perl has been upgraded to the new XPM version and renamed + as xpm1to3.perl + - ppmtoxpm2.c and ppmtoxpm2.1 have been upgraded too and renamed + ppmtoxpm.c and ppmtoxpm.1. In addition the xpmtoppm.c and xpmtoppm.1 + of the pbmplus package have been upgraded too. xpmtoppm can thus + convert XPM version 1 and 3 to a portable pixmap. These files should + replace the original ones which are part of the pbmplus package. See + the ppm.README file for more details. + - the library contains RCS variables which allows you to get revision + numbers with ident (which is part of the RCS package). The Id number + is an internal rcs number for my eyes only. The official one is found + in Version. + + BUGS CORRECTED: + - the memory management has been much improved in order to avoid + memory leaks. + - the XImage building algorythm has been changed to support correctly + different visual depths. There is special code to handle depths 1, 4, + 6, 8, 24, and 32 to build the image and send it in one whack, and + other depths are supported by building the image with XPutPixel which + is slow but sure. + - similar algorithms are used to read pixmaps and write them out. + + CHANGES TO THE DOC: + - the documentation presents the new XPM format. + + +2.8 (90/12/19) + + ******************************* WARNING ********************************* + Since the last release two structures have been modified and have now + bigger sizes, so ANY CODE USING THE libXPM2 NEEDS TO BE RECOMPILED. + ************************************************************************* + + NEW FEATURES: + - the ColorSymbol struct contains the new member 'pixel' which allow + to override default colors by giving a pixel value (in such a case + symbol value must be set to NULL), + - the XpmInfo struct contains the new member 'rgb_fname' in which one + can specify an rgb text file name while writing a pixmap with the + XWritePixmapFile function (otherwise this member should be set to + NULL). This way colorname will be searched and written out if found + instead of the RGB value, + - Imakefile originally provided by stolcke@ICSI.Berkeley.EDU, + - the old Makefile is now distributed as Makefile.noXtree and presents + install targets, + - the demo application is renamed sxpm (Show XPM), creates a window of + the size of the pixmap if no geometry is specified, prints out + messages instead of status when an error occurs, handles the new + option -p for overriding colors by giving a pixel value (not really + useful but is just here to show this new feature), handles the new + option -rgb for specifying an rgb text file, and ends on + keypress as buttonpress, + - defines for SYSV have been provided by Paul Breslaw + <paul@mecazh.uucp>, + - the distribution includes a new directory called converters which + contains xpm1to2 and xpm1to2c perl converters and a ppmtoxpm2 + converter provided by Paul Breslaw who upgraded the original ppmtoxpm + written by Mark W. Snitily <mark@zok.uucp>. + + CHANGES TO THE DOC: + - this file is created and will give old users a quick reference to + changes made from one release to the next one, + - documentation is changed to present the new ColorSymbol structure + and the way to override colors by giving a pixel value, and to present + the new XpmInfo structure and how to use it, + - a man page for sxpm is added to the distrib, + - the README file talks about sxpm and no more demo, and have + reference to the different converters. + +2.7 (90/11/12) + + NEW FEATURES: + - XReadPixmapFile reads from stdin if filename is NULL, + - XWritePixmapFile writes to stdin if filename is NULL, + - the demo application handles the new option -nod for no displaying + the pixmap in a window (useful when used as converter). + + CHANGES TO THE DOC: + - documentation about the new feature. + +2.6 (90/10/29) + + NEW FEATURES: + - from nazgul@alphalpha.com (Kee Hinckley): changes to make the + library usable as C++ code, and on Apollo without any warning. + + BUGS CORRECTED: + - from nazgul@alphalpha.com (Kee Hinckley): the xpm include files was + declaring XWritePixmapFile as taking in arg a Pixmap pointer instead + of a Pixmap. + +2.5 (90/10/17) + + BUGS CORRECTED: + - XWritePixmapFile was not closing the file while ending normaly. + +2.4 (90/09/06) + + NEW FEATURES: + - XReadPixmapFile reads from a piped uncompress if the given filename + ends by .Z or if filename.Z exists, + - XWritePixmapFile writes to a piped compress if the given filename + ends by .Z. + + BUGS CORRECTED: + - demo now deals with window manager. + + CHANGES TO THE DOC: + - documentation about compressed files management. + +2.3 (90/08/30) + + BUGS CORRECTED: + - handle monochrom display correctly, + - comments can be empty. + +2.2 (90/08/27) + + BUGS CORRECTED: + - when reading some invalid free was dumping core on some machine. + +2.1 (90/08/24) + + First distribution of XPM2. + diff --git a/src/xpm/doc/COPYRIGHT b/src/xpm/doc/COPYRIGHT new file mode 100644 index 0000000..951b7c3 --- /dev/null +++ b/src/xpm/doc/COPYRIGHT @@ -0,0 +1,30 @@ +/* + * Copyright 1990-92 GROUPE BULL + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of GROUPE BULL not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. GROUPE BULL makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * GROUPE BULL disclaims all warranties with regard to this software, + * including all implied warranties of merchantability and fitness, + * in no event shall GROUPE BULL be liable for any special, + * indirect or consequential damages or any damages + * whatsoever resulting from loss of use, data or profits, + * whether in an action of contract, negligence or other tortious + * action, arising out of or in connection with the use + * or performance of this software. + * + */ + +Arnaud LE HORS BULL Research FRANCE -- Koala Project + (XPM - X PixMap format version 2 & 3) + Internet: lehors@sophia.inria.fr +Surface Mail: Arnaud LE HORS, INRIA - Sophia Antipolis, + 2004, route des Lucioles, 06565 Valbonne Cedex -- FRANCE + Voice phone: (33) 93.65.77.71, Fax: (33) 93 65 77 66, Telex: 97 00 50 F diff --git a/src/xpm/doc/FILES b/src/xpm/doc/FILES new file mode 100644 index 0000000..1538e04 --- /dev/null +++ b/src/xpm/doc/FILES @@ -0,0 +1,42 @@ +CHANGES +COPYRIGHT +FILES +Imakefile +Makefile +Makefile.noXtree +README +XpmCrDataFP.c +XpmCrPFData.c +XpmRdFToP.c +XpmWrFFrP.c +XpmCrDataFI.c +XpmCrIFData.c +XpmRdFToI.c +XpmWrFFrI.c +XpmRdFToData.c +XpmWrFFrData.c +colas.sty +create.c +data.c +hashtable.c +misc.c +parse.c +plaid.xpm +plaid_mask.xpm +rgb.c +scan.c +sxpm.c +sxpm.man +xpm.h +xpm.tex +xpmP.h +converters +converters/xpm1to3.pl +converters/ppmtoxpm.1 +converters/ppmtoxpm.c +converters/xpmtoppm.1 +converters/xpmtoppm.c +converters/ppm.README +rename +name-3.0b-3.0c +name-3.0c-3.0 diff --git a/src/xpm/doc/Imakefile b/src/xpm/doc/Imakefile new file mode 100644 index 0000000..860aec4 --- /dev/null +++ b/src/xpm/doc/Imakefile @@ -0,0 +1,59 @@ +# Copyright 1990-92 GROUPE BULL -- See licence conditions in file COPYRIGHT +# +# XPM Imakefile - Arnaud LE HORS +# + + +#if (ProjectX < 5) + STD_DEFINES = LibraryDefines + CDEBUGFLAGS = LibraryCDebugFlags +#else +/* R5 needs another .tmpl file to find these #def's. This .tmpl file will */ +/* also set STD_DEFINES and CDEBUGFLAGS properly. */ +#include <Library.tmpl> +#endif + + INCLUDES = -I. + INSTALLFLAGS = $(INSTINCFLAGS) + LINTLIBS = $(LINTXTOLL) $(LINTXLIB) + +#ifdef OsNameDefines +OS_NAME_DEFINES = OsNameDefines +#endif + +## if your system doesn't provide strcasecmp add -DNEED_STRCASECMP +## if your system doesn't provide strdup add -DNEED_STRDUP +## if your system doesn't provide pipe remove -DZPIPE +DEFINES = -DZPIPE + +HEADERS = xpm.h + SRCS1 = data.c create.c misc.c rgb.c scan.c parse.c \ + XpmWrFFrP.c XpmRdFToP.c XpmCrPFData.c XpmCrDataFP.c \ + XpmWrFFrI.c XpmRdFToI.c XpmCrIFData.c XpmCrDataFI.c \ + hashtable.c XpmRdFToData.c XpmWrFFrData.c + SRCS = $(SRCS1) sxpm.c + OBJS1 = data.o create.o misc.o rgb.o scan.o parse.o \ + XpmWrFFrP.o XpmRdFToP.o XpmCrPFData.o XpmCrDataFP.o \ + XpmWrFFrI.o XpmRdFToI.o XpmCrIFData.o XpmCrDataFI.o \ + hashtable.o XpmRdFToData.o XpmWrFFrData.o + OBJS = sxpm.o + +NormalLibraryObjectRule() + +NormalLibraryTarget(Xpm,$(OBJS1)) +LintLibraryTarget(Xpm,$(SRCS1)) +InstallLibrary(Xpm,$(USRLIBDIR)) +InstallLintLibrary(Xpm,$(LINTLIBDIR)) + +InstallMultiple($(HEADERS),$(INCDIR)) +DependTarget() +NormalLintTarget($(SRCS1)) + + + DEPLIBS = libXpm.a $(DEPXTOOLLIB) $(DEPXLIB) +LOCAL_LIBRARIES = libXpm.a $(XTOOLLIB) $(XLIB) + +ComplexProgramTarget(sxpm) + +clean:: + $(RM) sxpmout.xpm diff --git a/src/xpm/doc/Makefile b/src/xpm/doc/Makefile new file mode 100644 index 0000000..4f08519 --- /dev/null +++ b/src/xpm/doc/Makefile @@ -0,0 +1,433 @@ +# Makefile generated by imake - do not edit! +# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $ +# +# The cpp used on this machine replaces all newlines and multiple tabs and +# spaces in a macro expansion with a single space. Imake tries to compensate +# for this, but is not always successful. +# + +# ------------------------------------------------------------------------- +# Makefile generated from "Imake.tmpl" and </tmp/IIf.a10758> +# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $ +# +# Platform-specific parameters may be set in the appropriate <vendor>.cf +# configuration files. Site-specific parameters should be set in the file +# site.def. Full rebuilds are recommended if any parameters are changed. +# +# If your C preprocessor does not define any unique symbols, you will need +# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing +# "make World" the first time). +# + +# ------------------------------------------------------------------------- +# site-specific configuration parameters that need to come before +# the platform-specific parameters - edit site.def to change + +# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $ + +# ------------------------------------------------------------------------- +# platform-specific configuration parameters - edit sun.cf to change + +# platform: $XConsortium: sun.cf,v 1.72.1.1 92/03/18 13:13:37 rws Exp $ + +# operating system: SunOS 4.1.1 + +# $XConsortium: sunLib.rules,v 1.7 91/12/20 11:19:47 rws Exp $ + +# ------------------------------------------------------------------------- +# site-specific configuration parameters that go after +# the platform-specific parameters - edit site.def to change + +# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $ + + TOP = . + CURRENT_DIR = . + + AR = ar clq + BOOTSTRAPCFLAGS = + CC = cc + AS = as + + COMPRESS = compress + CPP = /lib/cpp $(STD_CPP_DEFINES) + PREPROCESSCMD = cc -E $(STD_CPP_DEFINES) + INSTALL = install + LD = ld + LINT = lint + LINTLIBFLAG = -C + LINTOPTS = -axz + LN = ln -s + MV = mv + CP = cp + + RANLIB = ranlib + RANLIBINSTFLAGS = + + RM = rm -f + TROFF = ptroff -t + MSMACROS = -ms + TBL = tbl + EQN = eqn + STD_INCLUDES = + STD_CPP_DEFINES = + STD_DEFINES = + EXTRA_LOAD_FLAGS = + EXTRA_LIBRARIES = + TAGS = ctags + + SHAREDCODEDEF = -DSHAREDCODE + SHLIBDEF = -DSUNSHLIB + + PROTO_DEFINES = + + INSTPGMFLAGS = + + INSTBINFLAGS = -m 0755 + INSTUIDFLAGS = -m 4755 + INSTLIBFLAGS = -m 0644 + INSTINCFLAGS = -m 0444 + INSTMANFLAGS = -m 0444 + INSTDATFLAGS = -m 0444 + INSTKMEMFLAGS = -g kmem -m 2755 + + TOP_INCLUDES = -I$(INCROOT) + + CDEBUGFLAGS = -O + CCOPTIONS = -pipe + + ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES) + ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES) + CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES) + LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES) + + LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES) + + LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR) + + LDCOMBINEFLAGS = -X -r + DEPENDFLAGS = + + MACROFILE = sun.cf + RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut + + IMAKE_DEFINES = + + IRULESRC = $(CONFIGDIR) + IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES) + + ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \ + $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \ + $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES) + +# ------------------------------------------------------------------------- +# X Window System Build Parameters +# $XConsortium: Project.tmpl,v 1.138.1.1 92/11/11 09:49:19 rws Exp $ + +# ------------------------------------------------------------------------- +# X Window System make variables; this need to be coordinated with rules + + PATHSEP = / + USRLIBDIR = /usr/lib/X11R5 + BINDIR = /usr/bin/X11R5 + INCROOT = /usr/include/X11R5 + BUILDINCROOT = $(TOP) + BUILDINCDIR = $(BUILDINCROOT)/X11 + BUILDINCTOP = .. + INCDIR = $(INCROOT)/X11 + ADMDIR = /usr/adm + LIBDIR = /usr/lib/X11R5 + CONFIGDIR = $(LIBDIR)/config + LINTLIBDIR = $(USRLIBDIR)/lint + + FONTDIR = $(LIBDIR)/fonts + XINITDIR = $(LIBDIR)/xinit + XDMDIR = $(LIBDIR)/xdm + TWMDIR = $(LIBDIR)/twm + MANPATH = /usr/man + MANSOURCEPATH = $(MANPATH)/man + MANSUFFIX = n + LIBMANSUFFIX = 3 + MANDIR = $(MANSOURCEPATH)$(MANSUFFIX) + LIBMANDIR = $(MANSOURCEPATH)$(LIBMANSUFFIX) + NLSDIR = $(LIBDIR)/nls + PEXAPIDIR = $(LIBDIR)/PEX + XAPPLOADDIR = $(LIBDIR)/app-defaults + FONTCFLAGS = -t + + INSTAPPFLAGS = $(INSTDATFLAGS) + + IMAKE = imake + DEPEND = makedepend + RGB = rgb + + FONTC = bdftopcf + + MKFONTDIR = mkfontdir + MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier + + CONFIGSRC = $(TOP)/config + DOCUTILSRC = $(TOP)/doc/util + CLIENTSRC = $(TOP)/clients + DEMOSRC = $(TOP)/demos + LIBSRC = $(TOP)/lib + FONTSRC = $(TOP)/fonts + INCLUDESRC = $(TOP)/X11 + SERVERSRC = $(TOP)/server + UTILSRC = $(TOP)/util + SCRIPTSRC = $(UTILSRC)/scripts + EXAMPLESRC = $(TOP)/examples + CONTRIBSRC = $(TOP)/../contrib + DOCSRC = $(TOP)/doc + RGBSRC = $(TOP)/rgb + DEPENDSRC = $(UTILSRC)/makedepend + IMAKESRC = $(CONFIGSRC) + XAUTHSRC = $(LIBSRC)/Xau + XLIBSRC = $(LIBSRC)/X + XMUSRC = $(LIBSRC)/Xmu + TOOLKITSRC = $(LIBSRC)/Xt + AWIDGETSRC = $(LIBSRC)/Xaw + OLDXLIBSRC = $(LIBSRC)/oldX + XDMCPLIBSRC = $(LIBSRC)/Xdmcp + BDFTOSNFSRC = $(FONTSRC)/bdftosnf + BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf + BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf + MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir + FSLIBSRC = $(FONTSRC)/lib/fs + FONTSERVERSRC = $(FONTSRC)/server + EXTENSIONSRC = $(TOP)/extensions + XILIBSRC = $(EXTENSIONSRC)/lib/xinput + PEXLIBSRC = $(EXTENSIONSRC)/lib/PEXlib + PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX + +# $XConsortium: sunLib.tmpl,v 1.14.1.2 92/11/11 09:55:02 rws Exp $ + +SHLIBLDFLAGS = -assert pure-text +PICFLAGS = -pic + + DEPEXTENSIONLIB = + EXTENSIONLIB = -lXext + + DEPXLIB = $(DEPEXTENSIONLIB) + XLIB = $(EXTENSIONLIB) -lX11 + + DEPXMULIB = $(USRLIBDIR)/libXmu.sa.$(SOXMUREV) + XMULIBONLY = -lXmu + XMULIB = -lXmu + + DEPOLDXLIB = + OLDXLIB = -loldX + + DEPXTOOLLIB = $(USRLIBDIR)/libXt.sa.$(SOXTREV) + XTOOLLIB = -lXt + + DEPXAWLIB = $(USRLIBDIR)/libXaw.sa.$(SOXAWREV) + XAWLIB = -lXaw + + DEPXILIB = + XILIB = -lXi + + DEPPEXLIB = + PEXLIB = -lPEX5 + + SOXLIBREV = 4.10 + SOXTREV = 4.10 + SOXAWREV = 5.0 + SOOLDXREV = 4.10 + SOXMUREV = 4.10 + SOXEXTREV = 4.10 + SOXINPUTREV = 4.10 + SOPEXREV = 1.0 + + DEPXAUTHLIB = $(USRLIBDIR)/libXau.a + XAUTHLIB = -lXau + DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a + XDMCPLIB = -lXdmcp + + DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a + PHIGSLIB = -lphigs + + DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a + XBSDLIB = -lXbsd + + LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln + LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln + LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln + LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln + LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln + LINTXI = $(LINTLIBDIR)/llib-lXi.ln + LINTPEX = $(LINTLIBDIR)/llib-lPEX5.ln + LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln + + DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB) + + DEPLIBS1 = $(DEPLIBS) + DEPLIBS2 = $(DEPLIBS) + DEPLIBS3 = $(DEPLIBS) + +# ------------------------------------------------------------------------- +# Imake rules for building libraries, programs, scripts, and data files +# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $ + +# ------------------------------------------------------------------------- +# start of Imakefile + +# Copyright 1990-92 GROUPE BULL -- See licence conditions in file COPYRIGHT +# +# XPM Imakefile - Arnaud LE HORS +# + +# $XConsortium: Library.tmpl,v 1.12 92/03/20 15:05:19 rws Exp $ + + CC = cc + CCOPTIONS = +STD_DEFINES = +CDEBUGFLAGS = -O + + INCLUDES = -I. + INSTALLFLAGS = $(INSTINCFLAGS) + LINTLIBS = $(LINTXTOLL) $(LINTXLIB) + +OS_NAME_DEFINES = + +## if your system doesn't provide strcasecmp add -DNEED_STRCASECMP +## if your system doesn't provide strdup add -DNEED_STRDUP +## if your system doesn't provide pipe remove -DZPIPE +DEFINES = -DZPIPE + +HEADERS = xpm.h + SRCS1 = data.c create.c misc.c rgb.c scan.c parse.c \ + XpmWrFFrP.c XpmRdFToP.c XpmCrPFData.c XpmCrDataFP.c \ + XpmWrFFrI.c XpmRdFToI.c XpmCrIFData.c XpmCrDataFI.c \ + hashtable.c XpmRdFToData.c XpmWrFFrData.c + SRCS = $(SRCS1) sxpm.c + OBJS1 = data.o create.o misc.o rgb.o scan.o parse.o \ + XpmWrFFrP.o XpmRdFToP.o XpmCrPFData.o XpmCrDataFP.o \ + XpmWrFFrI.o XpmRdFToI.o XpmCrIFData.o XpmCrDataFI.o \ + hashtable.o XpmRdFToData.o XpmWrFFrData.o + OBJS = sxpm.o + +.c.o: + $(RM) $@ + $(CC) -c $(CFLAGS) $(_NOOP_) $*.c + +all:: libXpm.a + +libXpm.a: $(OBJS1) + $(RM) $@ + $(AR) $@ $(OBJS1) + $(RANLIB) $@ + +lintlib:: llib-lXpm.ln + +llib-lXpm.ln: $(SRCS1) + $(RM) $@ + $(LINT) $(LINTLIBFLAG)Xpm $(LINTFLAGS) $(SRCS1) + +install:: libXpm.a + @if [ -d $(DESTDIR)$(USRLIBDIR) ]; then set +x; \ + else (set -x; $(MKDIRHIER) $(DESTDIR)$(USRLIBDIR)); fi + $(INSTALL) -c $(INSTLIBFLAGS) libXpm.a $(DESTDIR)$(USRLIBDIR) + $(RANLIB) $(RANLIBINSTFLAGS) $(DESTDIR)$(USRLIBDIR)/libXpm.a + +install.ln:: llib-lXpm.ln + @if [ -d $(DESTDIR)$(LINTLIBDIR) ]; then set +x; \ + else (set -x; $(MKDIRHIER) $(DESTDIR)$(LINTLIBDIR)); fi + $(INSTALL) -c $(INSTLIBFLAGS) llib-lXpm.ln $(DESTDIR)$(LINTLIBDIR) + +install:: $(HEADERS) + @if [ -d $(DESTDIR)$(INCDIR) ]; then set +x; \ + else (set -x; $(MKDIRHIER) $(DESTDIR)$(INCDIR)); fi + @case '${MFLAGS}' in *[i]*) set +e;; esac; \ + for i in $(HEADERS); do \ + (set -x; $(INSTALL) -c $(INSTALLFLAGS) $$i $(DESTDIR)$(INCDIR)); \ + done + +depend:: + $(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS) + +lint: + $(LINT) $(LINTFLAGS) $(SRCS1) $(LINTLIBS) +lint1: + $(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS) + + DEPLIBS = libXpm.a $(DEPXTOOLLIB) $(DEPXLIB) +LOCAL_LIBRARIES = libXpm.a $(XTOOLLIB) $(XLIB) + + PROGRAM = sxpm + +all:: sxpm + +sxpm: $(OBJS) $(DEPLIBS) + $(RM) $@ + $(CC) -o $@ $(OBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS) + +saber_sxpm:: $(SRCS) + # load $(ALLDEFINES) $(SRCS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES) + +osaber_sxpm:: $(OBJS) + # load $(ALLDEFINES) $(OBJS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES) + +install:: sxpm + @if [ -d $(DESTDIR)$(BINDIR) ]; then set +x; \ + else (set -x; $(MKDIRHIER) $(DESTDIR)$(BINDIR)); fi + $(INSTALL) -c $(INSTPGMFLAGS) sxpm $(DESTDIR)$(BINDIR) + +install.man:: sxpm.man + @if [ -d $(DESTDIR)$(MANDIR) ]; then set +x; \ + else (set -x; $(MKDIRHIER) $(DESTDIR)$(MANDIR)); fi + $(INSTALL) -c $(INSTMANFLAGS) sxpm.man $(DESTDIR)$(MANDIR)/sxpm.$(MANSUFFIX) + +depend:: + $(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS) + +lint: + $(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS) +lint1: + $(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS) + +clean:: + $(RM) $(PROGRAM) + +clean:: + $(RM) sxpmout.xpm + +# ------------------------------------------------------------------------- +# common rules for all Makefiles - do not edit + +emptyrule:: + +clean:: + $(RM_CMD) "#"* + +Makefile:: + -@if [ -f Makefile ]; then set -x; \ + $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \ + else exit 0; fi + $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR) + +tags:: + $(TAGS) -w *.[ch] + $(TAGS) -xw *.[ch] > TAGS + +saber: + # load $(ALLDEFINES) $(SRCS) + +osaber: + # load $(ALLDEFINES) $(OBJS) + +# ------------------------------------------------------------------------- +# empty rules for directories that do not have SUBDIRS - do not edit + +install:: + @echo "install in $(CURRENT_DIR) done" + +install.man:: + @echo "install.man in $(CURRENT_DIR) done" + +Makefiles:: + +includes:: + +# ------------------------------------------------------------------------- +# dependencies generated by makedepend + diff --git a/src/xpm/doc/Makefile.noXtree b/src/xpm/doc/Makefile.noXtree new file mode 100644 index 0000000..1119883 --- /dev/null +++ b/src/xpm/doc/Makefile.noXtree @@ -0,0 +1,85 @@ +# Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT +# +# XPM Makefile - Arnaud LE HORS +# + +AR = ar r +CC = cc +RANLIB = ranlib +RM = rm -f +# on sysV, define this as cp. +INSTALL = install -c + +DVIPS = dvips + +CDEBUGFLAGS= -O + +# if your system doesn't provide strcasecmp add -DNEED_STRCASECMP +# if your system doesn't provide strdup add -DNEED_STRDUP +# if your system doesn't provide pipe remove -DZPIPE +DEFINES = -DZPIPE + +DESTBINDIR=/usr/local/bin/X11 +DESTLIBDIR=/usr/local/lib/X11 +DESTINCLUDEDIR=$(DESTLIBDIR)/xpm-include +MANDIR=/usr/man/manl + +LIBDIRS= -L/usr/lib/X11 -L. +LIBS= -lXpm -lXext -lXt -lX11 +OBJS= data.o create.o misc.o rgb.o scan.o parse.o hashtable.o \ + XpmWrFFrP.o XpmRdFToP.o XpmCrPFData.o XpmCrDataFP.o \ + XpmWrFFrI.o XpmRdFToI.o XpmCrIFData.o XpmCrDataFI.o \ + XpmRdFToData.o XpmWrFFrData.o + +CFLAGS= $(CDEBUGFLAGS) $(DEFINES) + +all: sxpm + +clean: + $(RM) *.o sxpm libXpm.a + +sxpm: libXpm.a sxpm.o + $(CC) $(CFLAGS) sxpm.o $(LIBDIRS) $(LIBS) -o sxpm + +libXpm.a: $(OBJS) + $(AR) libXpm.a $(OBJS) + $(RANLIB) libXpm.a + +install: install.lib install.sxpm install.man + +install.lib: + $(INSTALL) -m 0664 libXpm.a $(DESTLIBDIR) + cd $(DESTLIBDIR); $(RANLIB) libXpm.a + -mkdir $(DESTINCLUDEDIR) + -chmod ugo+rx $(DESTINCLUDEDIR) + $(INSTALL) -m 0444 xpm.h $(DESTINCLUDEDIR) + +install.sxpm: + $(INSTALL) -m 0755 sxpm $(DESTBINDIR) + +install.man: + $(INSTALL) -m 0644 sxpm.man $(MANDIR)/sxpm.l + +doc: xpm.ps + +xpm.ps: xpm.dvi + $(DVIPS) -o xpm.ps xpm + +xpm.dvi: xpm.tex + latex xpm + latex xpm + +print: xpm.ps + lpr xpm.ps + +# Other dependencies. +scan.o: xpmP.h +parse.o: xpmP.h +data.o: xpmP.h +create.o: xpmP.h +free.o: xpmP.h +rgb.o: xpmP.h +XpmWrPixF.o: xpmP.h +XpmRdPixF.o: xpmP.h +XpmCrPFData.o: xpmP.h +sxpm.o: xpm.h diff --git a/src/xpm/doc/README b/src/xpm/doc/README new file mode 100644 index 0000000..0807f5a --- /dev/null +++ b/src/xpm/doc/README @@ -0,0 +1,176 @@ +** Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT ** + + XPM Version 3 + +WHAT IS XPM? +============ + +XPM (X PixMap) is a format for storing/retrieving X pixmaps to/from files. + +Here is provided a library containing a set of four functions, similar to the +X bitmap functions as defined in the Xlib: XpmCreatePixmapFromData, +XpmCreateDataFromPixmap, XpmReadFileToPixmap and XpmWriteFileFromPixmap for +respectively including, storing, reading and writing this format, plus four +other: XpmCreateImageFromData, XpmCreateDataFromImage, XpmReadFileToImage and +XpmWriteFileFromImage for working with images instead of pixmaps. + +This new version provides a C includable format, defaults for different types +of display: monochrome/color/grayscale, hotspot coordinates and symbol names +for colors for overriding default colors when creating the pixmap. It provides +a mechanism for storing information while reading a file which is re-used +while writing. This way comments, default colors and symbol names aren't lost. +It also handles "transparent pixels" by returning a shape mask in addition to +the created pixmap. + +See the XPM Manual for more details. + +HOW TO GET XPM? +=============== + +New xpm updates are announced on the comp.windows.x newsgroup, and on the +"xpm-talk" list. All new "official" xpm releases can be found by ftp on: + + export.lcs.mit.edu (18.30.0.238) contrib (Boston, USA) + avahi.inria.fr (192.5.60.47) pub (Sophia Antipolis, France) + + +DOCUMENTATION: +============= + +Old users might read the CHANGES file for a history of changes interesting +the user. + +Read the docs (xpm.tex is the manual in LaTeX form). The documentation is in +LaTeX format (IMPORTANT: see the Makefile to know how to print it. The LaTeX +source should work with most dvi2ps or dvips programs. I use myself Tomas +Rokicki's dvips v5.0 that you can get by anonymous ftp on +labrea.stanford.edu). We can mail you a PostScript version of the +documentation if you are not able to print it, or you can grab one on the ftp +servers. + +INSTALLATION: +============ + +To obtain the XPM library, first uncompress and untar the compressed tar file +in an approriate directory. + +Then you can either compile xpm via "imake" or in a stand-alone way. + +WITH IMAKE: + + The Imakefile is provided. You should know how to use imake to build + the XPM Makefile, by executing "xmkmf" then do: + + make depend + make + + which will build the XPM library and sxpm application. + Then do: + + make install + make install.man + + which will install the library and the sxpm man page. + + If it fails, you may edit the Imakefile to add compilation flags to + suit your machine. + +WITHOUT IMAKE: + + To compile xpm, in the xpm directory you just created, do: + + make -f Makefile.noXtree + + Then to install it, do: + + make -f Makefile.noXtree install + +NOTE: if you compile with gcc, use "gcc -traditional", otherwise you will + have compilation warnings (but the code will work Ok) + +SXPM: +==== + +In addition to the library the sxpm tool is provided to show XPM file and +convert them from XPM2 to XPM version 3. If you have previously done 'make' or +'make all' you should have it yet, otherwise just do: + + make sxpm + +This application shows you most of the features of XPM and its source can be +used to quickly see how to use the provided functions + +By executing 'sxpm' without any option you will get the usage. + +Executing 'sxpm -plaid' will show a demo of the XpmCreatePixmapFromData +function. The pixmap is created from the static variable plaid defined in the +sxpm.c file. Sxpm will end when you press the key Q in the created window. + +Executing 'sxpm -plaid -s lines_in_mix blue' will show the feature of +overriding color symbols giving a colorname, and executing 'sxpm -p +lines_in_mix 1' will show overriding giving pixel value. + +Then you should try 'sxpm -plaid -o output' to get an output file using the +XpmWriteFileFromPixmap function. + +You can now try 'sxpm -plaid -o - -nod -rgb /usr/lib/X11/rgb.txt' to directly +get the pixmap printed out on the standard output with colornames instead of +rgb values. + +Then you should try 'sxpm plaid.xpm' to use the XpmReadFileToPixmap function, +and 'cat plaid_mask.xpm|sxpm' to see how "transparent pixels" are handled. + +The XpmCreatePixmapFromData function is on purpose called without any Xpminfo +pointer to show the utility of this one. Indeed, compare the color section of +the two files foo and bar obtained from 'sxpm -nod -plaid -o foo' and +'sxpm -nod plaid.xpm -o bar'. + +To end look at plaid_ext.xpm and try "sxpm -nod plaid_ext.xpm -v" to see how +extensions are handled. + +Of course, other combinations are allowed and should be tried. Thus, 'sxpm +plaid.xpm -o output -nod' will show you how to convert a file from XPM2 to a +XPM version 3 using sxpm. + +See the manual page for more detail. + +CONVERTERS: +========== + +In the converters directory you can find different converters about XPM. +There is a perl script xpm1to3.pl to convert XPM1 format file to XPM version +3. And there are files to build the converters ppmtoxpm and xpmtoppm; to get +instructions about how to build them you should read the corresponding +ppm.README file. + +KNOWN BUG: +========= + +If two symbols get the same color pixel when reading a pixmap, one will be +lost when writting it out. + +DISCUSSION: +========== + +There is a mailing list to discuss about XPM which is xpm-talk@sophia.inria.fr. +Any request to subscribe should be sent to xpm-talk-request@sophia.inria.fr. + +COPYRIGHT: +========== + + Copyright 1990-92 GROUPE BULL -- + See license conditions in the COPYRIGHT file of the XPM distribution + +Please mail any bug reports or modifications done, comments, suggestions, +requests for updates or patches to port on another machine to: + +lehors@sophia.inria.fr (INTERNET) + +33 (FRANCE) 93.65.77.71 (VOICE PHONE) + +Arnaud Le Hors (SURFACE MAIL) +Bull c/o Inria BP. 109 +2004, Route des lucioles +Sophia Antipolis +06561 Valbonne Cedex +FRANCE diff --git a/src/xpm/doc/colas.sty b/src/xpm/doc/colas.sty new file mode 100644 index 0000000..799e405 --- /dev/null +++ b/src/xpm/doc/colas.sty @@ -0,0 +1,294 @@ +% my add-on LaTeX macros +% to be used like in: +% \documentstyle[12pt,gwm]{report} + +% postscript inclusion: +\def\texpsfig#1#2#3 +{\vbox{\kern #3pt\hbox{\special{psfile=#1}\kern #2pt}}\typeout{(#1)}} + +% RCS version stripping +\def\RCSRevNum#1Revision: #2 ${#2} +\def\RCSRevVersion#1Version: #2 ${#2} + +\newlength{\colaslength} +\newlength{\colaslengthh} +\newlength{\colasmargin} + +\def\exemplefont{\footnotesize} +\def\usagefont{\large} +\def\usageupspace{\vspace{0.1mm}} +\newcommand{\Description} + {\list{}{\leftmargin 4cm \labelsep 0.1cm \labelwidth 3.9cm}} + +\def\descriptionlabel#1{\bf #1\hspace\labelsep\hfil} +\def\description + {\list{}{\leftmargin 2.4cm \labelsep 0.1cm \labelwidth 2.3cm + \let\makelabel\descriptionlabel}} + +\def\upspace{\vspace{-2mm}} +\def\undertablespace{\vspace{-3mm}} + +\def\Item#1#2{\upspace\pagebreak[1]\section*{\hspace{-7pt} + {\large\tt#1}{\normalsize\sf\quad ---\quad #2}}\vspace{-0.3cm}} + +\def\ITEMa#1#2{ + \Item{#1}{#2}\markright{#1} + \label{#1}} +\def\ITEMb#1#2#3{ + \Item{\vbox{\hbox{#1}\hbox{#2}}}{#3}\markright{#1} + \label{#1} \label{#2}} +\def\ITEMbi#1#2#3{ + \Item{\vbox{\hbox{#1}\hbox{#2}}}{#3}\markright{#1} + \label{#2}} +\def\ITEMc#1#2#3#4{ + \Item{\vbox{\hbox{#1}\hbox{#2}\hbox{#3}}}{#4}\markright{#1} + \label{#1}\label{#2} \label{#3}} +\def\ITEMci#1#2#3#4{ + \Item{\vbox{\hbox{#1}\hbox{#2}\hbox{#3}}}{#4}\markright{#1} + \label{#2}\label{#3}} +\def\ITEMd#1#2#3#4#5{ + \Item{\vbox{\hbox{#1}\hbox{#2}\hbox{#3}\hbox{#4}}}{#5}\markright{#1} + \label{#1}\label{#2}\label{#3}\label{#4}} +\def\ITEMe#1#2#3#4#5#6{ + \Item{ + \vbox{\hbox{#1}\hbox{#2}\hbox{#3}\hbox{#4}\hbox{#5}}}{#6}\markright{#1} + \label{#1}\label{#2}\label{#3}\label{#4}\label{#5}} +\def\ITEMf#1#2#3#4#5#6#7{ + \Item{ + \vbox{\hbox{#1}\hbox{#2}\hbox{#3}\hbox{#4}\hbox{#5}\hbox{#6}}}{#7} + \markright{#1} + \label{#1}\label{#2}\label{#3}\label{#4}\label{#5}\label{#6}} + +\newcommand{\context}[1]{ + Context used: + \begin{center}\begin{tabular}{@{\tt}l@{\hspace{1cm}}@{\rm}p{7cm}} + \multicolumn{1}{c}{\bf Variable}&\multicolumn{1}{c}{\bf used for}\\ + \hline \multicolumn{2}{l}{\undertablespace}\\ + #1 + \end{tabular}\end{center}} + +\newcommand{\contextdim}[2]{ + \setlength{\colaslength}{7cm} + \addtolength{\colaslength}{#1} + Context used: + \begin{center}\begin{tabular}{@{\tt}l@{\hspace{1cm}}@{\rm}p{\colaslength}} + \multicolumn{1}{c}{\bf Variable}&\multicolumn{1}{c}{\bf used for}\\ + \hline \multicolumn{2}{l}{\undertablespace}\\ + #2 + \end{tabular}\end{center}} + +\newcommand{\desctable}[3]{ + \begin{center}\begin{tabular}{@{\bf}l@{\hspace{1cm}}@{\rm}p{7cm}} + \multicolumn{1}{c}{\bf #1}&\multicolumn{1}{c}{\bf #2}\\ + \hline \multicolumn{2}{l}{\undertablespace}\\ + #3 + \end{tabular}\end{center}} + +\newcommand{\desctabledim}[4]{ + \setlength{\colaslength}{7cm} + \addtolength{\colaslength}{#1} + \begin{center}\begin{tabular}{@{\bf}l@{\hspace{1cm}}@{\rm}p{\colaslength}} + \multicolumn{1}{c}{\bf #2}&\multicolumn{1}{c}{\bf #3}\\ + \hline \multicolumn{2}{l}{\undertablespace}\\ + #4 + \end{tabular}\end{center}} + +\newcommand{\exemples}[2]{ + #1{\exemplefont + \begin{center}\begin{tabular}{@{\tt}l@{\hspace{1cm}}@{\rm}p{5cm}} + #2 + \end{tabular}\end{center}}} + +\newcommand{\exemplesdim}[3]{ + \setlength{\colaslength}{5cm} + \addtolength{\colaslength}{#1} + #2{\exemplefont + \begin{center}\begin{tabular}{@{\tt}l@{\hspace{1cm}}@{\rm}p{\colaslength}} + #3 + \end{tabular}\end{center}}} + +\newcommand{\usagetype}[1]{{\sl #1}\vspace{0.2cm}} +\newcommand{\usagetyped}[2]{{\sl #1}\quad{\it (#2)}\vspace{0.2cm}} +\newcommand{\see}[1]{{\tt #1}} +\newcommand{\seep}[1]{{\tt #1}, p~\pageref{#1}} +\newcommand{\seensp}[1]{{\tt #1} (see p~\pageref{#1})} +\newcommand{\seesnp}[1]{(see {\tt #1}, p~\pageref{#1})} +\newcommand{\seeref}[1]{{\tt #1} (see \ref{#1}, p~\pageref{#1})} +\newcommand{\seesp}[1]{(see \ref{#1}, p~\pageref{#1})} + +\def\smalldesc#1#2#3{#1\\} +\newcommand{\bigdesc}[2]{ + \setlength{\colaslength}{300pt} + \settowidth{\colaslengthh}{{\tt #1}} + \addtolength{\colaslength}{-\colaslengthh} + \begin{center}\begin{tabular} + {@{\tt}l@{\hspace{0.5cm}}@{\sf}p{\colaslength}@{\hspace{0.4cm}}@{\bf}r} + \multicolumn{1}{c}{\bf Object}&\multicolumn{1}{c}{\bf Description}&{\bf p}\\ + \hline \multicolumn{3}{l}{\undertablespace}\\ + #2 + \end{tabular}\end{center}} + +\newcommand{\desc}[4]{ + \setlength{\colaslength}{250pt} + \settowidth{\colaslengthh}{{\tt #1}} + \addtolength{\colaslength}{-\colaslengthh} + \begin{center}\begin{tabular} +{@{\tt}l@{\hspace{0.5cm}}@{\sf}p{\colaslength}} + \multicolumn{1}{c}{\bf #2}&\multicolumn{1}{c}{\bf #3}\\ + \hline \multicolumn{2}{l}{\undertablespace}\\ + #4 + \end{tabular}\end{center}} + +\newcommand{\contextdimtt}[2]{ + \setlength{\colaslength}{250pt} + \settowidth{\colaslengthh}{{\tt #1}} + \addtolength{\colaslength}{-\colaslengthh} + Context used: + \begin{center}\begin{tabular}{@{\tt}l@{\hspace{1cm}}@{\rm}p{\colaslength}} + \multicolumn{1}{c}{\bf Variable}&\multicolumn{1}{c}{\bf used for}\\ + \hline \multicolumn{2}{l}{\undertablespace}\\ + #2 + \end{tabular}\end{center}} + +\def\itemtt#1{\item[{\tt #1}]} +\def\itemit#1{\item[{\it #1}]} + + +% SIZE of page +%============= + +\def\fullpage{\if@twoside \oddsidemargin 35pt \evensidemargin -8pt +\marginparsep 10pt \marginparpush 10pt \marginparwidth 10pt +\else \oddsidemargin 0pt \evensidemargin 0pt +\marginparwidth 30pt\fi +\textwidth 450pt \setlength{\colasmargin}{0pt} +\def\colaspm{\hspace{0pt}}\def\colasmm{\hspace{0pt}} +\def\colassmm{\hspace{0pt}}\def\colastitledisp{\hspace{0pt}} +} +\def\mediumpage{\if@twoside \oddsidemargin 75pt \evensidemargin 32pt +\marginparsep 10pt \marginparpush 10pt \marginparwidth 40pt +\else \oddsidemargin 43pt \evensidemargin 63pt +\marginparwidth 30pt\fi +\textwidth 410pt \setlength{\colasmargin}{0pt} +\def\colaspm{\hspace{40pt}}\def\colasmm{\hspace{-40pt}} +\def\colassmm{\hspace{-20pt}}\def\colastitledisp{\hspace{-45pt}} +} +\def\smallpage{\if@twoside \oddsidemargin 135pt \evensidemargin 92pt +\marginparsep 10pt \marginparpush 10pt \marginparwidth 80pt +\else \oddsidemargin 123pt \evensidemargin 123pt +\marginparwidth 30pt \fi +\textwidth 350pt +\setlength{\colasmargin}{100pt} +\def\colaspm{\hspace{100pt}}\def\colasmm{\hspace{-100pt}} +\def\colassmm{\hspace{-60pt}}\def\colastitledisp{\hspace{-75pt}} +} + +\smallpage +\topmargin -30pt \headheight 12pt \headsep 25pt \footheight 12pt \footskip +30pt +\textheight 680pt \columnsep 10pt \columnseprule 0pt +\footnotesep 12pt \skip\footins 6pt plus 2pt minus 2pt +\floatsep 12pt plus 2pt minus 2pt \textfloatsep 20pt plus 2pt minus 4pt +\intextsep 12pt plus 2pt minus 2pt \@maxsep 20pt \dblfloatsep 12pt plus 2pt +minus 2pt \dbltextfloatsep 20pt plus 2pt minus 4pt \@dblmaxsep 20pt +\@fptop 0pt plus 1fil \@fpsep 8pt plus 2fil \@fpbot 0pt plus 1fil +\@dblfptop 0pt plus 1fil \@dblfpsep 8pt plus 2fil \@dblfpbot 0pt plus 1fil + +\parskip 5pt plus 1pt \parindent 0pt \topsep 2pt plus 1pt minus 1pt +\partopsep 0pt plus 1pt minus 1pt \itemsep 2pt plus 1pt minus 1pt + +\reversemarginpar +\@mparswitchfalse + +%% abbrevs + +\def\GWM{\sc Gwm} +\def\WOOL{\sc Wool} + +%% fonts +\def\Huge{\@setsize\Huge{30pt}\xxvpt\@xxvpt} + +%% chapter + +\def\@makechapterhead#1{ \vspace*{1pt} { \parindent 0pt \raggedright + \Huge\bf \colasmm + \ifnum \c@secnumdepth >\m@ne \thechapter \quad \fi + #1\par + \nobreak \vskip 20pt + \colasmm{\vbox{\hbox{\vrule height 5pt width450pt depth -3pt} + \vspace*{-1.1cm} + \hbox{\vrule height 0.0pt width450pt depth 0.4pt}}} + \nobreak \vskip 50pt \nobreak } } + +\def\@makeschapterhead#1{ \vspace*{1pt} { \parindent 0pt \raggedright + \Huge \bf \colasmm #1\par + \nobreak \vskip 80pt } } + +\def\chapter{\clearpage \thispagestyle{pagenum} \global\@topnum\z@ +\@afterindentfalse \secdef\@chapter\@schapter} +\def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne + \refstepcounter{chapter} + \typeout{\@chapapp\space\thechapter.} + \addcontentsline{toc}{chapter}{\protect + \numberline{\thechapter}#1}\else + \addcontentsline{toc}{chapter}{#1}\fi + \chaptermark{#1} + \addtocontents{lof}{\protect\addvspace{10pt}} +\addtocontents{lot}{\protect\addvspace{10pt}} \if@twocolumn +\@topnewpage[\@makechapterhead{#2}] + \else \@makechapterhead{#2} + \@afterheading \fi} +\def\@schapter#1{\if@twocolumn \@topnewpage[\@makeschapterhead{#1}] + \else \@makeschapterhead{#1} + \@afterheading\fi} + +%% sections + +\def\section{\@startsection {section}{1}{\z@}{-3.5ex plus -1ex minus + -.2ex}{2.3ex plus .2ex}{\Large\bf\colasmm}} +\def\subsection{\@startsection{subsection}{2}{\z@}{-3.25ex plus -1ex minus + -.2ex}{1.5ex plus .2ex}{\large\bf\colassmm}} +\def\subsubsection{\@startsection{subsubsection}{3}{\z@}{-3.25ex plus +-1ex minus -.2ex}{1.5ex plus .2ex}{\normalsize\bf}} +\def\paragraph{\@startsection + {paragraph}{4}{\z@}{3.25ex plus 1ex minus .2ex}{-1em}{\normalsize\bf}} +\def\subparagraph{\@startsection + {subparagraph}{4}{\parindent}{3.25ex plus 1ex minus + .2ex}{-1em}{\normalsize\bf}} + +%% headings + +\if@twoside \def\ps@headings{\def\@oddfoot{} +\def\@evenfoot{}\def\@evenhead{ +\colasmm\makebox[0pt][l]{\vrule height-4pt width450pt depth4.3pt} +\bf\thepage\hfill \sl \leftmark} +\def\@oddhead{ +\colasmm\makebox[0pt][l]{\vrule height-4pt width450pt depth4.3pt} +\sl \rightmark \hfill\bf\thepage} +\def\chaptermark##1{\markboth {\uppercase{\ifnum \c@secnumdepth +>\m@ne + \@chapapp\ \thechapter. \ \fi ##1}}{}}\def\sectionmark##1{\markright +{\uppercase{\ifnum \c@secnumdepth >\z@ + \thesection. \ \fi ##1}}}} +\else \def\ps@headings{\def\@oddfoot{}\def\@evenfoot{}\def\@oddhead{\hbox +{}\sl \rightmark \hfill \rm\thepage}\def\chaptermark##1{\markright +{\uppercase{\ifnum \c@secnumdepth >\m@ne + \@chapapp\ \thechapter. \ \fi ##1}}}} +\fi + +\if@twoside \def\ps@pagenum{\def\@oddfoot{} +\def\@evenfoot{}\def\@evenhead{ +\colasmm\bf\thepage\hfill} +\def\@oddhead{ +\colasmm\hfill\bf\thepage} +\def\chaptermark##1{\markboth {\uppercase{\ifnum \c@secnumdepth +>\m@ne + \@chapapp\ \thechapter. \ \fi ##1}}{}}\def\sectionmark##1{\markright +{\uppercase{\ifnum \c@secnumdepth >\z@ + \thesection. \ \fi ##1}}}} +\else \def\ps@pagenum{\def\@oddfoot{}\def\@evenfoot{}\def\@oddhead{\hbox +{}\hfil \bf\thepage}\def\chaptermark##1{\markright +{\uppercase{\ifnum \c@secnumdepth >\m@ne + \@chapapp\ \thechapter. \ \fi ##1}}}} +\fi + diff --git a/src/xpm/doc/name-3.0b-3.0c b/src/xpm/doc/name-3.0b-3.0c new file mode 100644 index 0000000..04c687b --- /dev/null +++ b/src/xpm/doc/name-3.0b-3.0c @@ -0,0 +1,48 @@ +s/^XCreatePixmapFromData$/XpmCreatePixmapFromData/g +s/^XCreatePixmapFromData\([^a-zA-Z_]\)/XpmCreatePixmapFromData\1/g +s/\([^a-zA-Z_]\)XCreatePixmapFromData$/\1XpmCreatePixmapFromData/g +s/\([^a-zA-Z_]\)XCreatePixmapFromData\([^a-zA-Z_]\)/\1XpmCreatePixmapFromData\2/g +s/^XCreateDataFromPixmap$/XpmCreateDataFromPixmap/g +s/^XCreateDataFromPixmap\([^a-zA-Z_]\)/XpmCreateDataFromPixmap\1/g +s/\([^a-zA-Z_]\)XCreateDataFromPixmap$/\1XpmCreateDataFromPixmap/g +s/\([^a-zA-Z_]\)XCreateDataFromPixmap\([^a-zA-Z_]\)/\1XpmCreateDataFromPixmap\2/g +s/^XReadPixmapFile$/XpmReadPixmapFile/g +s/^XReadPixmapFile\([^a-zA-Z_]\)/XpmReadPixmapFile\1/g +s/\([^a-zA-Z_]\)XReadPixmapFile$/\1XpmReadPixmapFile/g +s/\([^a-zA-Z_]\)XReadPixmapFile\([^a-zA-Z_]\)/\1XpmReadPixmapFile\2/g +s/^XWritePixmapFile$/XpmWritePixmapFile/g +s/^XWritePixmapFile\([^a-zA-Z_]\)/XpmWritePixmapFile\1/g +s/\([^a-zA-Z_]\)XWritePixmapFile$/\1XpmWritePixmapFile/g +s/\([^a-zA-Z_]\)XWritePixmapFile\([^a-zA-Z_]\)/\1XpmWritePixmapFile\2/g +s/^XFreeXpmAttributes$/XpmFreeAttributes/g +s/^XFreeXpmAttributes\([^a-zA-Z_]\)/XpmFreeAttributes\1/g +s/\([^a-zA-Z_]\)XFreeXpmAttributes$/\1XpmFreeAttributes/g +s/\([^a-zA-Z_]\)XFreeXpmAttributes\([^a-zA-Z_]\)/\1XpmFreeAttributes\2/g +s/^PixmapColorError$/XpmPixmapColorError/g +s/^PixmapColorError\([^a-zA-Z_]\)/XpmPixmapColorError\1/g +s/\([^a-zA-Z_]\)PixmapColorError$/\1XpmPixmapColorError/g +s/\([^a-zA-Z_]\)PixmapColorError\([^a-zA-Z_]\)/\1XpmPixmapColorError\2/g +s/^PixmapSuccess$/XpmPixmapSuccess/g +s/^PixmapSuccess\([^a-zA-Z_]\)/XpmPixmapSuccess\1/g +s/\([^a-zA-Z_]\)PixmapSuccess$/\1XpmPixmapSuccess/g +s/\([^a-zA-Z_]\)PixmapSuccess\([^a-zA-Z_]\)/\1XpmPixmapSuccess\2/g +s/^PixmapOpenFailed$/XpmPixmapOpenFailed/g +s/^PixmapOpenFailed\([^a-zA-Z_]\)/XpmPixmapOpenFailed\1/g +s/\([^a-zA-Z_]\)PixmapOpenFailed$/\1XpmPixmapOpenFailed/g +s/\([^a-zA-Z_]\)PixmapOpenFailed\([^a-zA-Z_]\)/\1XpmPixmapOpenFailed\2/g +s/^PixmapFileInvalid$/XpmPixmapFileInvalid/g +s/^PixmapFileInvalid\([^a-zA-Z_]\)/XpmPixmapFileInvalid\1/g +s/\([^a-zA-Z_]\)PixmapFileInvalid$/\1XpmPixmapFileInvalid/g +s/\([^a-zA-Z_]\)PixmapFileInvalid\([^a-zA-Z_]\)/\1XpmPixmapFileInvalid\2/g +s/^PixmapNoMemory$/XpmPixmapNoMemory/g +s/^PixmapNoMemory\([^a-zA-Z_]\)/XpmPixmapNoMemory\1/g +s/\([^a-zA-Z_]\)PixmapNoMemory$/\1XpmPixmapNoMemory/g +s/\([^a-zA-Z_]\)PixmapNoMemory\([^a-zA-Z_]\)/\1XpmPixmapNoMemory\2/g +s/^PixmapColorFailed$/XpmPixmapColorFailed/g +s/^PixmapColorFailed\([^a-zA-Z_]\)/XpmPixmapColorFailed\1/g +s/\([^a-zA-Z_]\)PixmapColorFailed$/\1XpmPixmapColorFailed/g +s/\([^a-zA-Z_]\)PixmapColorFailed\([^a-zA-Z_]\)/\1XpmPixmapColorFailed\2/g +s/^ColorSymbol$/XpmColorSymbol/g +s/^ColorSymbol\([^a-zA-Z_]\)/XpmColorSymbol\1/g +s/\([^a-zA-Z_]\)ColorSymbol$/\1XpmColorSymbol/g +s/\([^a-zA-Z_]\)ColorSymbol\([^a-zA-Z_]\)/\1XpmColorSymbol\2/g diff --git a/src/xpm/doc/name-3.0c-3.0 b/src/xpm/doc/name-3.0c-3.0 new file mode 100644 index 0000000..3187d46 --- /dev/null +++ b/src/xpm/doc/name-3.0c-3.0 @@ -0,0 +1,32 @@ +s/^XpmPixmapColorError$/XpmColorError/g +s/^XpmPixmapColorError\([^a-zA-Z_]\)/XpmColorError\1/g +s/\([^a-zA-Z_]\)XpmPixmapColorError$/\1XpmColorError/g +s/\([^a-zA-Z_]\)XpmPixmapColorError\([^a-zA-Z_]\)/\1XpmColorError\2/g +s/^XpmPixmapSuccess$/XpmSuccess/g +s/^XpmPixmapSuccess\([^a-zA-Z_]\)/XpmSuccess\1/g +s/\([^a-zA-Z_]\)XpmPixmapSuccess$/\1XpmSuccess/g +s/\([^a-zA-Z_]\)XpmPixmapSuccess\([^a-zA-Z_]\)/\1XpmSuccess\2/g +s/^XpmPixmapOpenFailed$/XpmOpenFailed/g +s/^XpmPixmapOpenFailed\([^a-zA-Z_]\)/XpmOpenFailed\1/g +s/\([^a-zA-Z_]\)XpmPixmapOpenFailed$/\1XpmOpenFailed/g +s/\([^a-zA-Z_]\)XpmPixmapOpenFailed\([^a-zA-Z_]\)/\1XpmOpenFailed\2/g +s/^XpmPixmapFileInvalid$/XpmFileInvalid/g +s/^XpmPixmapFileInvalid\([^a-zA-Z_]\)/XpmFileInvalid\1/g +s/\([^a-zA-Z_]\)XpmPixmapFileInvalid$/\1XpmFileInvalid/g +s/\([^a-zA-Z_]\)XpmPixmapFileInvalid\([^a-zA-Z_]\)/\1XpmFileInvalid\2/g +s/^XpmPixmapNoMemory$/XpmNoMemory/g +s/^XpmPixmapNoMemory\([^a-zA-Z_]\)/XpmNoMemory\1/g +s/\([^a-zA-Z_]\)XpmPixmapNoMemory$/\1XpmNoMemory/g +s/\([^a-zA-Z_]\)XpmPixmapNoMemory\([^a-zA-Z_]\)/\1XpmNoMemory\2/g +s/^XpmPixmapColorFailed$/XpmColorFailed/g +s/^XpmPixmapColorFailed\([^a-zA-Z_]\)/XpmColorFailed\1/g +s/\([^a-zA-Z_]\)XpmPixmapColorFailed$/\1XpmColorFailed/g +s/\([^a-zA-Z_]\)XpmPixmapColorFailed\([^a-zA-Z_]\)/\1XpmColorFailed\2/g +s/^XpmReadPixmapFile$/XpmReadFileToPixmap/g +s/^XpmReadPixmapFile\([^a-zA-Z_]\)/XpmReadFileToPixmap\1/g +s/\([^a-zA-Z_]\)XpmReadPixmapFile$/\1XpmReadFileToPixmap/g +s/\([^a-zA-Z_]\)XpmReadPixmapFile\([^a-zA-Z_]\)/\1XpmReadFileToPixmap\2/g +s/^XpmWritePixmapFile$/XpmWriteFileFromPixmap/g +s/^XpmWritePixmapFile\([^a-zA-Z_]\)/XpmWriteFileFromPixmap\1/g +s/\([^a-zA-Z_]\)XpmWritePixmapFile$/\1XpmWriteFileFromPixmap/g +s/\([^a-zA-Z_]\)XpmWritePixmapFile\([^a-zA-Z_]\)/\1XpmWriteFileFromPixmap\2/g diff --git a/src/xpm/doc/plaid.xpm b/src/xpm/doc/plaid.xpm new file mode 100644 index 0000000..b0e9200 --- /dev/null +++ b/src/xpm/doc/plaid.xpm @@ -0,0 +1,34 @@ +/* XPM */ +static char * plaid[] = { +/* plaid pixmap + * width height ncolors chars_per_pixel */ +"22 22 4 2 ", +/* colors */ +" c red m white s light_color ", +"Y c green m black s lines_in_mix ", +"+ c yellow m white s lines_in_dark ", +"x m black s dark_color ", +/* pixels */ +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +"Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +"x x x x x x x x x x x x x x x x x x x x x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x " +} ; diff --git a/src/xpm/doc/plaid_mask.xpm b/src/xpm/doc/plaid_mask.xpm new file mode 100644 index 0000000..167d338 --- /dev/null +++ b/src/xpm/doc/plaid_mask.xpm @@ -0,0 +1,35 @@ +/* XPM */ +static char * plaid[] = { +/* plaid pixmap + * width height ncolors chars_per_pixel */ +"22 22 5 2", +/* colors */ +". c red m white s light_color ", +"Y c green m black s lines_in_mix ", +"+ c yellow m white s lines_in_dark ", +"x m black s dark_color ", +" c none s mask ", +/* pixels */ +" x x x x x + x x x x x ", +" . x x x x x x x x x x x ", +" . x x x x x x + x x x x x ", +" . x . x x x x x x x x x x x ", +" . x . x x x x x x + x x x x x ", +" Y Y Y Y Y + x + x + x + x + x + ", +" x x . x . x x x x x x + x x x x x ", +" . x . x . x . x x x x x x x x x x x ", +" . x x x . x . x x x x x x + x x x x x ", +" . x . x . x . x . x x x x x x x x x x x ", +" . x . x x x . x . x x x x x x + x x x x x ", +". . . . . x . . . . . x . x . x Y x . x . x ", +". . . . . x . . . . . . x . x . Y . x . x . ", +". . . . . x . . . . . x . x . x Y x . x . x ", +". . . . . x . . . . . . x . x . Y . x . x . ", +". . . . . x . . . . . x . x . x Y x . x . x ", +"x x x x x x x x x x x x x x x x x x x x x x ", +". . . . . x . . . . . x . x . x Y x . x . x ", +". . . . . x . . . . . . x . x . Y . x . x . ", +". . . . . x . . . . . x . x . x Y x . x . x ", +". . . . . x . . . . . . x . x . Y . x . x . ", +". . . . . x . . . . . x . x . x Y x . x . x " +} ; diff --git a/src/xpm/doc/xpm.tex b/src/xpm/doc/xpm.tex new file mode 100644 index 0000000..7614e89 --- /dev/null +++ b/src/xpm/doc/xpm.tex @@ -0,0 +1,849 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% XPM MANUAL % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% adjust these for centering on the page: +% upper-left corner of frame in title page must be at 60mm,60mm from +% upper-left corner of the page + +% normal (A4) on our Apple Laserwriter with dvi2ps +%\hoffset 0cm +%\voffset 0cm +% normal (A4 & Letter) on our Apple Laserwriter with dvips v5.0 +\hoffset -5.5mm +\voffset 0cm +% our imagen +%\hoffset -0.9cm +%\voffset -2.2cm + +% NOTE: the following line MUST be commented out! +%\includeonly{standard} + +\makeindex + +\documentstyle[twoside,colas]{article} + +% IF YOUR DVI PRINTER CHOKES ON INCLUDED POSTSCRIPT FILES +% by the \special command, uncomment the following line: +% \def\texpsfig#1#2#3{\fbox{Figure ``#1''}} + + +\pagestyle{headings} +\begin{document} + +\thispagestyle{empty} +\ +\hbox{\colastitledisp +\vbox{ +\vspace{3cm} +\begin{center} +\fboxrule 0.4pt \fboxsep 1pt +\fbox{\fboxrule 3pt \fboxsep 30pt \fbox{\Huge\bf XPM Manual}} +\end{center} +\vspace{2cm} +\begin{center} +\huge +The {\bf X} {\bf P}ix{\bf M}ap Format +\end{center} +\vspace{2cm} +\begin{center} +\Large Version \RCSRevVersion$Version: 3.2c $\\ +\end{center} +\vspace{2cm} +\begin{center} +\LARGE\sf Arnaud Le Hors\\ +\large\tt lehors@sophia.inria.fr +\end{center} +\vspace{1cm} +\vspace{1cm} +\begin{center} +\copyright BULL 1990-92 +\end{center} +}} + +\newpage + +\section*{Copyright restrictions} +{\bf\begin{flushleft} +Copyright 1990-92 GROUPE BULL\\ +\end{flushleft}} + +{\sf +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, provided +that the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation, and that the name of GROUPE BULL not be used in advertising +or publicity pertaining to distribution of the software without specific, +written prior permission. GROUPE BULL makes no representations about the +suitability of this software for any purpose. It is provided ``as is'' +without express or implied warranty. + +GROUPE BULL disclaims all warranties with regard to this software, +including all implied warranties of merchantability and fitness, +in no event shall GROUPE BULL be liable for any special, +indirect or consequential damages or any damages +whatsoever resulting from loss of use, data or profits, +whether in an action of contract, negligence or other tortious +action, arising out of or in connection with the use +or performance of this software. +} + +\section*{Acknowledgements} + +I want to thank my team partner and friend Colas Nahaboo who proposed me this +project, and who actively participates to its design. I also want to thank all +the users who help me to improve the library by giving feed back and sending +bug reports. + +\begin{flushright} +{\Large Arnaud Le Hors.\quad} +{\small +KOALA Project -- BULL Research c/o INRIA\\ +2004 route des Lucioles -- 06565 Valbonne Cedex -- FRANCE\\ +} +\end{flushright} + +\section*{Support} + +\sloppy +You can mail any question or suggestion relative to {\bf XPM} by electronic +mail to {\tt lehors@sophia.inria.fr}. There is also a mailing list, please +mail requests to {\tt xpm-talk-request@sophia.inria.fr} to subscribe. You can +find the latest release by anonymous ftp on avahi.inria.fr (138.96.24.30) or +export.lcs.mit.edu (18.30.0.238), and also an archive of the mailing list on +avahi. + + +\newpage +\section{Introduction} +First, Why another image format? We (Koala team at Bull Research, France) +felt that most images bundled with X applications will be small "icons", and +that since many applications are color-customizable, existing image formats +such as gif, tiff, iff, etc... were intended for big images with well-defined +colors and so weren't adapted to the task. So {\bf XPM} was designed with +these criterions in mind: +\begin{itemize} +\item be editable by hand (under emacs, vi...). Color pixmap editors aren't +available everywhere. +\item be includable in C code. It is unreasonable to load +1000 pixmap files on each start of an application. +\item be a portable, mailable ascii format. +\item provide defaults for monochrome/color/grayscale renderings. +\item provide overriding of colors. This way if the user wants your application +to be bluish instead of greenish, you can use the SAME icon files. +\item allow comments to be included in the file. +\item compression must be managed apart of the format. +\end{itemize} + +\newpage +\section{The {\bf XPM} Format} + +The {\bf XPM} format presents a C syntax, in order to provide the ability to +include {\bf XPM} files in C and C++ programs. It is in fact an array of +strings composed of six different sections as follows: +{\tt +\begin{quote} +/* XPM */ +static char* {\tt <variable\_name>}[] = \{ + +<Values> + +<Colors> + +<Pixels> + +<Extensions> + +\}; +\end{quote} +} + +The words are separated by a white space which can be composed of space and +tabulation characters. + +The {\tt <Values>} section is a string containing four or six integers in base +10 that correspond to: the pixmap width and height, the number of colors, the +number of characters per pixel (so there is no limit on the number of colors), +and, optionally the hotspot coordinates and the {\bf XPMEXT} tag if there is +any extension following the {\tt <Pixels>} section. + +{\tt <width> <height> <ncolors> <cpp> [<x\_hotspot> <y\_hotspot>] [XPMEXT]} + +The {\tt Colors} section contains as many strings as there are colors, and +each string is as follows: + +{\tt <chars> \{<key> <color>\}+} + +Where {\tt <chars>} is the {\tt <chars\_per\_pixel>} length string (not +surrounded by anything) representing the pixels, {\tt <color>} is the +specified color, and {\tt <key>} is a keyword describing in which context this +color should be used. Currently the keys may have the following values: + +\begin{tabbing} +\hspace{1cm}\= g4 \= for 4-level grayscale\kill +\> m \>for mono visual\\ +\> s \> for symbolic name\\ +\> g4 \> for 4-level grayscale\\ +\> g \> for grayscale with more than 4 levels\\ +\> c \> for color visual +\end{tabbing} + +Colors can be specified by giving the colorname, a \# foolwed by the RGB code, +or a \% followed by the HSV code. The symbolic name provides the ability of +specifying the colors at load time and not to hard-code them in the file. +Also the string {\bf None} can be given as a colorname to mean +``transparent''. Transparency is handled by providing a masking bitmap in +addition to the pixmap. + +The {\tt <Pixels>} section is composed by {\tt <height>} strings of {\tt +<width>} * {\tt <chars\_per\_pixel>} characters, where every {\tt +<chars\_per\_pixel>} length string must be one of the previously defined +groups in the {\tt <Colors>} section. + +Then follows the {\tt <Extensions>} section which must be labeled, if not +empty, in the {\tt <Values>} section as previously described. +This section may be composed by several {\tt <Extension>} subsections which +may be of two types: + +\begin{itemize} +\item[] one stand alone string composed as follows: + +{\tt XPMEXT <extension-name> <extension-data>} + +\item[] or a block composed by several strings: + +{\tt XPMEXT <extension-name>} + +{\tt <related extension-data composed of several strings>} + +\end{itemize} + +Finally, if not empty, this section must end by the following string: + +{\tt XPMENDEXT} + +To avoid possible conflicts with extension names in shared files, they should +be prefixed by the name of the company. This would ensure unicity. + +\vspace{0.5cm} +Below is an example which is the XPM file of a plaid pixmap. This is a 22x22 +pixmap, with 4 colors and 2 characters per pixel. The hotspot coordinates are +(0, 0). There are symbols and default colors for color and monochrome visuals. +Finally there are two extensions. + +{\small \begin{verbatim} + +/* XPM */ +static char * plaid[] = { +/* plaid pixmap + * width height ncolors chars_per_pixel */ +"22 22 4 2 0 0 XPMEXT", +/* colors */ +" c red m white s light_color ", +"Y c green m black s lines_in_mix ", +"+ c yellow m white s lines_in_dark ", +"x m black s dark_color ", +/* pixels */ +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +"Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +"x x x x x x x x x x x x x x x x x x x x x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x " +"XPMEXT ext1 data1", +"XPMEXT ext2", +"data2_1", +"data2_2", +"XPMENDEXT" +}; + +\end{verbatim}} + +\newpage +\section{The {\bf XPM} Library} + +The XPM library provides a set of Xlib-level functions which allows to deal +with images, pixmaps, XPM file, and data (included XPM file) in many ways. +This section describes these functions and how to use them. + +\vspace{.5cm} +To provide a simple interface all these functions take, in addition to their +main arguments such as the display, a structure called {\bf XpmAttributes}. +This structure may be considered as composed of two different groups of +members. The first one is composed of attributes to pass data such as colormap +and visual and attributes to retrieve returned data such as pixmap's width and +height. The second group provides a way to rewrite an {\bf XPM} file without +losing information such as comments, color defaults and symbolic names which +may exist in the original file (i.e. the {\bf XpmInfo} structure in {\bf XPM 2}). +The {\bf XpmAttributes} structure is defined as follows: + +{\small \begin{tabbing} + +\hspace{1cm}\= XpmColorSymbol *colorsymbols; \=/* List of color symbols */\kill +typedef struct \{ \\ +\> unsigned long valuemask; \>/* Specifies which attributes are defined */\\ +\\ +\> Visual *visual; \>/* Specifies the visual to use */ \\ +\> Colormap colormap; \>/* Specifies the colormap to use */ \\ +\> unsigned int depth; \>/* Specifies the depth */ \\ +\> unsigned int width; \>/* Returns the width of the created pixmap */\\ +\> unsigned int height; \>/* Returns the height of the created pixmap */\\ +\> unsigned int x\_hotspot; \>/* Returns the x hotspot's coordinate */\\ +\> unsigned int y\_hotspot; \>/* Returns the y hotspot's coordinate */ \\ +\> unsigned int cpp; \>/* Specifies the number of char per pixel */ \\ +\> Pixel *pixels; \>/* List of used color pixels */ \\ +\> unsigned int npixels; \>/* Number of pixels */\\ +\> XpmColorSymbol *colorsymbols;\>/* Array of color symbols to override */ \\ +\> unsigned int numsymbols; \>/* Number of symbols */ \\ +\> char *rgb\_fname; \>/* RGB text file name */ \\ +\> unsigned int nextensions; \>/* Number of extensions */ \\ +\> XpmExtension *extensions; \>/* Array of extensions */ \\ +\\ +\> /* Infos */ \\ +\> int ncolors; \>/* Number of colors */ \\ +\> char ***colorTable; \>/* Color table pointer */ \\ +\> char *hints\_cmt; \>/* Comment of the hints section */ \\ +\> char *colors\_cmt; \>/* Comment of the colors section */ \\ +\> char *pixels\_cmt; \>/* Comment of the pixels section */ \\ +\> unsigned int mask\_pixel; \>/* Transparent pixel's color table index */\\ +\\ +\> /* Color Allocation Directives */ \\ +\> unsigned int exactColors; \>/* Only use exact colors for visual */ \\ +\> unsigned int closeness; \>/* Allowable RGB deviation */ \\ +\\ +\} XpmAttributes; + +\end{tabbing}} + +The valuemask is the bitwise inclusive OR of the valid attribute mask bits. If +the valuemask is zero, the attributes are ignored and not referenced. And +default values are taken for needed attributes which are not specified. + +The colorTable is a two dimensional array of strings, organized as follows: +\begin{flushleft} +\hspace{.5cm}colorTable[color\#][0] points to the character string associated +to the color.\\ +\hspace{.5cm}colorTable[color\#][1] points to the symbolic name of the color.\\ +\hspace{.5cm}colorTable[color\#][2] points to the default color for monochrome +visuals.\\ +\hspace{.5cm}colorTable[color\#][3] points to the default color for 4-level +grayscale visuals.\\ +\hspace{.5cm}colorTable[color\#][4] points to the default color for other +grayscale visuals.\\ +\hspace{.5cm}colorTable[color\#][5] points to the default color for color +visuals. +\end{flushleft} + +Comments are limited to a single comment string by section. If more exist in +the read file, then only the last comment of each section will be stored. + +To get information back while writing out to a file, you just have to set +the mask bits {\bf XpmReturnInfos} to the valuemask of an {\bf XpmAttributes} +structure that you pass to the {\bf XpmReadFileToPixmap} function while reading +the file, and then give the structure back to the {\bf XpmWriteFileFromPixmap} +function while writing. + +\vspace{.5cm} +To allow overriding of colors at load time the {\bf XPM} library defines the +{\bf XpmColorSymbol} structure which contains: + +\begin{tabbing} +\hspace{1cm}\= char *value; \hspace{1.5cm}\= /* Color value */\kill +typedef struct \{\\ +\> char *name; \> /* Symbolic color name */\\ +\> char *value;\> /* Color value */\\ +\> Pixel pixel;\> /* Color pixel */\\ +\} XpmColorSymbol; +\end{tabbing} + +To override default colors at load time, you just have to pass, via the {\bf +XpmAttributes} structure, a list of {\bf XpmColorSymbol} elements containing +the desired colors to the {\bf XpmReadFileToPixmap} or {\bf +XpmCreatePixmapFromData} {\bf XPM} functions. These colors can be specified by +giving the color name in the value member or directly by giving the +corresponding pixel in the pixel member. In the latter case the value member +must be set to {\bf NULL} otherwise the given pixel will not be considered. + +In addition, is is possible to set the pixel for a specific color {\bf value} +at load time by setting the color name to NULL, and setting the value and pixel +fields appropriately. For example, by setting the color name to NULL, the +value to ``red'' and the pixel to 51, all symbolic colors that are assigned to +``red'' will be set to pixel 51. It is even possible to specify the pixel used +for the transparent color ``none'' when no mask is required. + +\vspace{.5cm} +To pass and retrieve extension data use the {\bf XpmExtension} structure which +is defined below: + +\begin{tabbing} +\hspace{1cm}\= unsigned int nlines; \hspace{1cm}\= /* */ \kill +typedef struct \{ \\ +\> char *name; \> /* name of the extension */ \\ +\> unsigned int nlines; \> /* number of lines in this extension */ \\ +\> char **lines; \> /* pointer to the extension array of strings */ \\ +\} XpmExtension; +\end{tabbing} + +To retrieve possible extension data stored in an {\bf XPM} file or data, you +must set the mask bits {\bf XpmReturnExtensions} to the valuemask of an {\bf +XpmAttributes} structure that you pass to the read function you use. Then the +same structure may be passed the same way to any write function if you set the +mask bits {\bf XpmExtensions} to the valuemask. + +\vspace{.5cm} +To create a pixmap from an {\bf XPM} file, use {\bf XpmReadFileToPixmap}. + +\begin{flushleft} + +int XpmReadFileToPixmap({\it display, d, filename, \\ +\hspace{3cm}pixmap\_return, shapemask\_return, attributes})\\ + +\hspace{1cm}Display {\it *display;}\\ +\hspace{1cm}Drawable {\it d;}\\ +\hspace{1cm}char {\it *filename;}\\ +\hspace{1cm}Pixmap {\it *pixmap\_return;}\\ +\hspace{1cm}Pixmap {\it *shapemask\_return;}\\ +\hspace{1cm}XpmAttributes {\it *attributes;} + +\end{flushleft} + +\begin{description} + +\itemit{display} Specifies the connection to the X server. +\itemit{d} Specifies which screen the pixmap is created on. +\itemit{filename} Specifies the file name to use. +\itemit{pixmap\_return} Returns the pixmap which is created. +\itemit{shapemask\_return} Returns the shapemask which is created, if any. +\itemit{attributes} Specifies the location of an {\bf XpmAttributes} structure +to get and store information. + +\end{description} + +The {\bf XpmReadFileToPixmap} function reads in a file containing a pixmap in +the {\bf XPM} format. If the file cannot be opened, {\bf XpmReadFileToPixmap} +returns {\bf XpmOpenFailed}. If the file can be opened but does not +contain valid {\bf XPM} pixmap data, it returns {\bf XpmFileInvalid}. If +insufficient working storage is allocated, it returns {\bf XpmNoMemory}. + +If the passed {\bf XpmAttributes} structure pointer is not {\bf NULL}, {\bf +XpmReadFileToPixmap} looks for the following attributes: {\bf XpmVisual}, {\bf +XpmColormap}, {\bf XpmDepth}, {\bf XpmColorSymbols}, {\bf XpmExactColors}, +{\bf XpmCloseness}, {\bf XpmReturnPixels}, {\bf XpmReturnExtensions}, +{\bf XpmReturnInfos}, and sets the {\bf XpmSize} and possibly the +{\bf XpmHotspot} attributes when returning. + +{\bf XpmReadFileToPixmap} allocates colors, as read from the file or possibly +overridden as specified in the {\bf XpmColorSymbols} attributes. The colors +are allocated dependently on the type of visual and on the default colors. If +no default value exits for the specified visual, it first looks for other +defaults nearer to the monochrome visual type and secondly nearer to the color +visual type. If the color which is found is not valid (cannot parse it), it +looks for another default one according to the same algorithm. + +If allocating a color fails, and the {\bf closeness} attribute is set, it +tries to find a color already in the colormap that is closest to the desired +color, and uses that. If no color can be found that is within {\bf closeness} +of the Red, Green and Blue components of the desired color, it reverts to +trying other default values as explained above. + +The RGB Components are integers within the range 0 (black) to 65535 (white). +A closeness of less than 10000, for example, will cause only quite close colors +to be matched, while a closeness of more than 50000 will allow quite +dissimilar colors to match. Specifying a closeness of more than 65535 will +allow any color to match, thus forcing the icon to be drawn in color no matter +how bad the colormap is. The value 40000 seems to be about right for many +situations requiring reasonable but not perfect matches. With this setting the +color must only be within the same general area of the RGB cube as the desired +color. + +If the {\bf exactColors} attribute is set it then returns {\bf XpmColorError}, +otherwise it creates the pixmap and returns XpmSuccess. If no color is found, +and no close color exists or is wanted, and all visuals have been exhausted, +{\bf XpmColorFailed} is returned. + +{\bf XpmReadFileToPixmap} returns the created pixmap to pixmap\_return if not +{\bf NULL} and possibly the created shapemask to shapemask\_return if not +{\bf NULL}. If required it stores into the {\bf XpmAttributes} structure the +list of the used pixels and possible comments, color defaults and symbols. +When finished the caller must free the pixmaps using {\bf XFreePixmap}, the +colors using {\bf XFreeColors}, and possibly the data returned into the +{\bf XpmAttributes} using {\bf XpmFreeAttributes}. + +In addition on system which support such features {\bf XpmReadFileToPixmap} +deals with compressed files by forking an uncompress process and reading from +the piped result. It assumes that the specified file is compressed if the +given file name ends by .Z. In case the file name does not end so, {\bf +XpmReadFileToPixmap} first looks for a file of which the name is the given one +followed by .Z; then if such a file does not exist, it looks for the given +file (assumed as not compressed). And if instead of a file name {\bf NULL} is +passed to {\bf XpmReadFileToPixmap}, it reads from the standard input. + +\vspace{.5cm} +To write out a pixmap to an {\bf XPM} file, use {\bf XpmWriteFileFromPixmap}. + +\begin{flushleft} + +int XpmWriteFileFromPixmap({\it display, filename, pixmap, shapemask,\\ +\hspace{3cm}attributes})\\ + +\hspace{1cm}Display {\it *display;}\\ +\hspace{1cm}char {\it *filename;}\\ +\hspace{1cm}Pixmap {\it pixmap;}\\ +\hspace{1cm}Pixmap {\it shapemask;}\\ +\hspace{1cm}XpmAttributes {\it *attributes;} + +\end{flushleft} + +\begin{description} + +\itemit{display} Specifies the connection to the X server. +\itemit{filename} Specifies the file name to use. +\itemit{pixmap} Specifies the pixmap. +\itemit{shapemask} Specifies the shape mask pixmap. +\itemit{attributes} Specifies the location of an {\bf XpmAttributes} structure +containing information. + +\end{description} + +The {\bf XpmWriteFileFromPixmap} function writes a pixmap and its possible +shapemask out to a file in the {\bf XPM} format. If the file cannot be opened, +it returns {\bf XpmOpenFailed}. If insufficient working storage is +allocated, it returns {\bf XpmNoMemory}. If no error occurs then it +returns {\bf XpmSuccess}. + +If the passed {\bf XpmAttributes} structure pointer is not {\bf NULL}, {\bf +XpmWriteFileFromPixmap} look for the following attributes: {\bf XpmColormap}, +{\bf XpmSize}, {\bf XpmHotspot}, {\bf XpmCharsPerPixel}, {\bf XpmRgbFilename}, +{\bf XpmInfos} and {\bf XpmExtensions}. + +If the {\bf XpmSize} attributes are not defined {\bf XpmWriteFileFromPixmap} +performs an {\bf XGetGeometry} operation. If the filename contains an +extension such as ``.xpm'' it is cut off when writing out to the pixmap +variable name. If the {\bf XpmInfos} attributes are defined it writes out +possible stored information such as comments, color defaults and symbol. +Finally if the {\bf XpmRgbFilename} attribute is defined, {\bf +XpmWriteFileFromPixmap} searches for color names in this file and if found +writes them out instead of the rgb values. + +In addition on system which support such features if the given file name ends +by .Z it is assumed to be a compressed file. Then, {\bf XpmWriteFileFromPixmap} +writes to a piped compress process. And if instead of a file name {\bf NULL} +is passed to {\bf XpmWriteFileFromPixmap}, it writes to the standard output. + +\vspace{.5cm} +To create a pixmap from an {\bf XPM} file directly included in a program, use +{\bf XpmCreatePixmapFromData}. + +\begin{flushleft} + +int XpmCreatePixmapFromData({\it display, d, data, \\ +\hspace{3cm}pixmap\_return, shapemask\_return, attributes})\\ + +\hspace{1cm}Display {\it *display;}\\ +\hspace{1cm}Drawable {\it d;}\\ +\hspace{1cm}char {\it **data;}\\ +\hspace{1cm}Pixmap {\it *pixmap\_return;}\\ +\hspace{1cm}Pixmap {\it *shapemask\_return;}\\ +\hspace{1cm}XpmAttributes {\it *attributes;} + +\end{flushleft} + +\begin{description} + +\itemit{display} Specifies the connection to the X server. +\itemit{d} Specifies which screen the pixmap is created on. +\itemit{data} Specifies the location of the pixmap data. +\itemit{pixmap\_return} Returns the pixmap which is created. +\itemit{shapemask\_return} Returns the shape mask pixmap which is created if +any. +\itemit{attributes} Specifies the location of an {\bf XpmAttributes} structure +to get and store information, or {\bf NULL}. + +\end{description} + +The {\bf XpmCreatePixmapFromData} function allows you to include in your C +program an {\bf XPM} pixmap file which was written out by {\bf +XpmWriteFileFromPixmap} without reading in the pixmap file. + +{\bf XpmCreatePixmapFromData} exactly works as {\bf +Xpm\-Read\-File\-To\-Pixmap} does and returns the same way. It just reads data +instead of a file. Here again, it is the caller's responsibility to free the +pixmaps, the colors and possibly the data returned into the {\bf +XpmAttributes} structure. + +\vspace{.5cm} +In some cases, one may want to create an {\bf XPM} data from a pixmap in order +to be able to create a pixmap from this data using the {\bf +XpmCreatePixmapFromData} function later on. To do so use {\bf +XpmCreateDataFromPixmap}. + +\begin{flushleft} + +int XpmCreateDataFromPixmap({\it display, data\_return, pixmap, shapemask,\\ +\hspace{3cm}attributes})\\ + +\hspace{1cm}Display {\it *display;}\\ +\hspace{1cm}char {\it ***data\_return;}\\ +\hspace{1cm}Pixmap {\it pixmap;}\\ +\hspace{1cm}Pixmap {\it shapemask;}\\ +\hspace{1cm}XpmAttributes {\it *attributes;} + +\end{flushleft} + +\begin{description} + +\itemit{display} Specifies the connection to the X server. +\itemit{data\_return} Returns the data which is created. +\itemit{pixmap} Specifies the pixmap. +\itemit{shapemask} Specifies the shape mask pixmap. +\itemit{attributes} Specifies the location of an {\bf XpmAttributes} structure +containing information. + +\end{description} + +The {\bf XpmCreateDataFromPixmap} function exactly works as {\bf +Xpm\-Write\-File\-From\-Pixmap} does and returns the same way. It just writes +to a single block malloc'ed data instead of to a file. It is the caller's +responsibility to free the data when finished. + +\vspace{.5cm} +To do the same than the four functions described above do but with images +instead of pixmaps use the functions {\bf XpmReadFileToImage}, {\bf +XpmWriteFileFromImage}, {\bf XpmCreateImageFromData}, {\bf +XpmCreateDataFromImage}. + +\vspace{.2cm} +{\bf XpmReadFileToImage} creates an image from an {\bf XPM} file. + +\begin{flushleft} + +int XpmReadFileToImage({\it display, filename, \\ +\hspace{3cm}image\_return, shapeimage\_return, attributes})\\ + +\hspace{1cm}Display {\it *display;}\\ +\hspace{1cm}char {\it *filename;}\\ +\hspace{1cm}XImage {\it **image\_return;}\\ +\hspace{1cm}XImage {\it **shapeimage\_return;}\\ +\hspace{1cm}XpmAttributes {\it *attributes;} + +\end{flushleft} + +\begin{description} + +\itemit{display} Specifies the connection to the X server. +\itemit{filename} Specifies the file name to use. +\itemit{image\_return} Returns the image which is created. +\itemit{shapeimage\_return} Returns the shape mask image which is created if +any. +\itemit{attributes} Specifies the location of an {\bf XpmAttributes} structure +to get and store information. + +\end{description} + +\vspace{.5cm} +{\bf XpmWriteFileFromImage} writes out an image to an {\bf XPM} file. + +\begin{flushleft} + +int XpmWriteFileFromImage({\it display, filename, image, shapeimage,\\ +\hspace{3cm}attributes})\\ + +\hspace{1cm}Display {\it *display;}\\ +\hspace{1cm}char {\it *filename;}\\ +\hspace{1cm}XImage {\it *image;}\\ +\hspace{1cm}XImage {\it *shapeimage;}\\ +\hspace{1cm}XpmAttributes {\it *attributes;} + +\end{flushleft} + +\begin{description} + +\itemit{display} Specifies the connection to the X server. +\itemit{filename} Specifies the file name to use. +\itemit{image} Specifies the image. +\itemit{shapeimage} Specifies the shape mask image. +\itemit{attributes} Specifies the location of an {\bf XpmAttributes} structure +containing information. + +\end{description} + +\vspace{.5cm} +{\bf XpmCreateImageFromData} creates an image from an {\bf XPM} file directly included in a program. + +\begin{flushleft} + +int XpmCreateImageFromData({\it display, data, \\ +\hspace{3cm}image\_return, shapeimage\_return, attributes})\\ + +\hspace{1cm}Display {\it *display;}\\ +\hspace{1cm}char {\it **data;}\\ +\hspace{1cm}XImage {\it **image\_return;}\\ +\hspace{1cm}XImage {\it **shapeimage\_return;}\\ +\hspace{1cm}XpmAttributes {\it *attributes;} + +\end{flushleft} + +\begin{description} + +\itemit{display} Specifies the connection to the X server. +\itemit{data} Specifies the location of the image data. +\itemit{image\_return} Returns the image which is created. +\itemit{shapeimage\_return} Returns the shape mask image which is created if +any. +\itemit{attributes} Specifies the location of an {\bf XpmAttributes} structure +to get and store information, or {\bf NULL}. + +\end{description} + +\vspace{.5cm} +{\bf XpmCreateDataFromImage} creates an {\bf XPM} data from an image. + +\begin{flushleft} + +int XpmCreateDataFromImage({\it display, data\_return, image, shapeimage,\\ +\hspace{3cm}attributes})\\ + +\hspace{1cm}Display {\it *display;}\\ +\hspace{1cm}char {\it ***data\_return;}\\ +\hspace{1cm}XImage {\it *image;}\\ +\hspace{1cm}XImage {\it *shapeimage;}\\ +\hspace{1cm}XpmAttributes {\it *attributes;} + +\end{flushleft} + +\begin{description} + +\itemit{display} Specifies the connection to the X server. +\itemit{data\_return} Returns the data which is created. +\itemit{image} Specifies the image. +\itemit{shapeimage} Specifies the shape mask image. +\itemit{attributes} Specifies the location of an {\bf XpmAttributes} structure +containing information. + +\end{description} + +These four functions work exactly the same way than the four ones previously +described. + +\vspace{.5cm} +To directly tranform an {\bf XPM} file to and from an {\bf XPM} data +array, without requiring an open X display, use {\bf +XpmReadFileToData} and {\bf XpmWriteFileFromData}. + +\vspace{.2cm} +{\bf XpmReadFileToData} allocates and fills an XPM data array from an {\bf XPM} file. + +\begin{flushleft} + +int XpmReadFileToData({\it filename, data\_return})\\ + +\hspace{1cm}char {\it *filename;}\\ +\hspace{1cm}char {\it ***data\_return;} + +\end{flushleft} + +\begin{description} + +\itemit{filename} Specifies the file name to read. +\itemit{data\_return} Returns the data array created. + +\end{description} + +\vspace{.5cm} +{\bf XpmWriteFileFromData} writes an {\b XPM} data array to an {\bf XPM} file. + +\begin{flushleft} + +int XpmWriteFileFromData({\it filename, data})\\ + +\hspace{1cm}char {\it *filename;}\\ +\hspace{1cm}char {\it **data;} + +\end{flushleft} + +\begin{description} + +\itemit{filename} Specifies the file name to write. +\itemit{data} Specifies the {\b XPM} data array to read. + +\end{description} + +\vspace{.5cm} +To free possible data stored into an {\bf XpmAttributes} structure use {\bf +XpmFreeAttributes}. + +\begin{flushleft} + +int XpmFreeAttributes({\it attributes})\\ + +\hspace{1cm}XpmAttributes {\it *attributes;} + +\end{flushleft} + +\begin{description} + +\itemit{attributes} Specifies the structure to free. + +\end{description} + +The {\bf XpmFreeAttributes} frees the structure members which have been +malloc'ed: the pixels list and the infos members (comments strings and color +table). + +\vspace{.5cm} +To dynamically allocate an {\bf XpmAttributes} structure use the {\bf +Xpm\-Attributes\-Size} function. + +\begin{flushleft} + +int XpmAttributesSize() + +\end{flushleft} + +The {\bf XpmAttributesSize} function provides application using dynamic +libraries with a safe way to allocate and then refer to an {\bf XpmAttributes} +structure, disregarding whether the {\bf XpmAttributes} structure size has +changed or not since compiled. + +\vspace{.5cm} +To free data possibly stored into an array of {\bf XpmExtension} use {\bf +XpmFreeExtensions}. + +\begin{flushleft} + +int XpmFreeExtensions({\it extensions, nextensions})\\ + +\hspace{1cm}XpmExtension {\it *extensions;}\\ +\hspace{1cm}int {\it nextensions;} + +\end{flushleft} + +\begin{description} + +\itemit{extensions} Specifies the array to free. +\itemit{nextensions} Specifies the number of extensions. + +\end{description} + +This function frees all data stored in every extension and the array itself. +Note that {\bf XpmFreeAttributes} call this function and thus most of the time +it should not need to be explicitly called. + +\end{document} diff --git a/src/xpm/hashtable.c b/src/xpm/hashtable.c new file mode 100644 index 0000000..e457e26 --- /dev/null +++ b/src/xpm/hashtable.c @@ -0,0 +1,205 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* hashtable.c: * +* * +* XPM library * +* * +* Developed by Arnaud Le Hors * +* this originaly comes from Colas Nahaboo as a part of Wool * +* * +\*****************************************************************************/ + +#include "xpmP.h" + +LFUNC(AtomMake, xpmHashAtom, (char *name, void *data)); +LFUNC(HashTableGrows, int, (xpmHashTable *table)); + +static xpmHashAtom +AtomMake(name, data) /* makes an atom */ + char *name; /* WARNING: is just pointed to */ + void *data; +{ + xpmHashAtom object = (xpmHashAtom) malloc(sizeof(struct _xpmHashAtom)); + if (object) { + object->name = name; + object->data = data; + } + return object; +} + +/************************\ +* * +* hash table routines * +* * +\************************/ + +/* + * Hash function definition: + * HASH_FUNCTION: hash function, hash = hashcode, hp = pointer on char, + * hash2 = temporary for hashcode. + * INITIAL_TABLE_SIZE in slots + * HASH_TABLE_GROWS how hash table grows. + */ + +/* Mock lisp function */ +#define HASH_FUNCTION hash = (hash << 5) - hash + *hp++; +/* #define INITIAL_HASH_SIZE 2017 */ +#define INITIAL_HASH_SIZE 256 /* should be enough for colors */ +#define HASH_TABLE_GROWS size = size * 2; + +/* aho-sethi-ullman's HPJ (sizes should be primes)*/ +#ifdef notdef +#define HASH_FUNCTION hash <<= 4; hash += *hp++; \ + if(hash2 = hash & 0xf0000000) hash ^= (hash2 >> 24) ^ hash2; +#define INITIAL_HASH_SIZE 4095 /* should be 2^n - 1 */ +#define HASH_TABLE_GROWS size = size << 1 + 1; +#endif + +/* GNU emacs function */ +/* +#define HASH_FUNCTION hash = (hash << 3) + (hash >> 28) + *hp++; +#define INITIAL_HASH_SIZE 2017 +#define HASH_TABLE_GROWS size = size * 2; +*/ + +/* end of hash functions */ + +/* + * The hash table is used to store atoms via their NAME: + * + * NAME --hash--> ATOM |--name--> "foo" + * |--data--> any value which has to be stored + * + */ + +/* + * xpmHashSlot gives the slot (pointer to xpmHashAtom) of a name + * (slot points to NULL if it is not defined) + * + */ + +xpmHashAtom * +xpmHashSlot(table, s) + xpmHashTable *table; + char *s; +{ + xpmHashAtom *atomTable = table->atomTable; + unsigned int hash, hash2; + xpmHashAtom *p; + char *hp = s; + char *ns; + + hash = 0; + while (*hp) { /* computes hash function */ + HASH_FUNCTION + } + p = atomTable + hash % table->size; + while (*p) { + ns = (*p)->name; + if (ns[0] == s[0] && strcmp(ns, s) == 0) + break; + p--; + if (p < atomTable) + p = atomTable + table->size - 1; + } + return p; +} + +static int +HashTableGrows(table) + xpmHashTable *table; +{ + xpmHashAtom *atomTable = table->atomTable; + int size = table->size; + xpmHashAtom *t, *p; + int i; + int oldSize = size; + + t = atomTable; + HASH_TABLE_GROWS + table->size = size; + table->limit = size / 3; + atomTable = (xpmHashAtom *) malloc(size * sizeof(*atomTable)); + if (!atomTable) + return (XpmNoMemory); + table->atomTable = atomTable; + for (p = atomTable + size; p > atomTable;) + *--p = NULL; + for (i = 0, p = t; i < oldSize; i++, p++) + if (*p) { + xpmHashAtom *ps = xpmHashSlot(table, (*p)->name); + *ps = *p; + } + free(t); + return (XpmSuccess); +} + +/* + * xpmHashIntern(table, name, data) + * an xpmHashAtom is created if name doesn't exist, with the given data. + */ + +int +xpmHashIntern(table, tag, data) + xpmHashTable *table; + char *tag; + void *data; +{ + xpmHashAtom *slot; + + if (!*(slot = xpmHashSlot(table, tag))) { + /* undefined, make a new atom with the given data */ + if (!(*slot = AtomMake(tag, data))) + return (XpmNoMemory); + if (table->used >= table->limit) { + int ErrorStatus; + xpmHashAtom new = *slot; + if ((ErrorStatus = HashTableGrows(table)) != XpmSuccess) + return(ErrorStatus); + table->used++; + return (XpmSuccess); + } + table->used++; + } + return (XpmSuccess); +} + +/* + * must be called before allocating any atom + */ + +int +xpmHashTableInit(table) + xpmHashTable *table; +{ + xpmHashAtom *p; + xpmHashAtom *atomTable; + + table->size = INITIAL_HASH_SIZE; + table->limit = table->size / 3; + table->used = 0; + atomTable = (xpmHashAtom *) malloc(table->size * sizeof(*atomTable)); + if (!atomTable) + return (XpmNoMemory); + for (p = atomTable + table->size; p > atomTable;) + *--p = NULL; + table->atomTable = atomTable; + return (XpmSuccess); +} + +/* + * frees a hashtable and all the stored atoms + */ + +void +xpmHashTableFree(table) + xpmHashTable *table; +{ + xpmHashAtom *p; + xpmHashAtom *atomTable = table->atomTable; + for (p = atomTable + table->size; p > atomTable;) + if (*--p) + free(*p); + free(atomTable); + table->atomTable = NULL; +} diff --git a/src/xpm/misc.c b/src/xpm/misc.c new file mode 100644 index 0000000..a34608c --- /dev/null +++ b/src/xpm/misc.c @@ -0,0 +1,206 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* misc.c: * +* * +* XPM library * +* Miscellaneous utilities * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpmP.h" + +/* + * Free the computed color table + */ + +xpmFreeColorTable(colorTable, ncolors) + char ***colorTable; + int ncolors; +{ + int a, b; + char ***ct, **cts; + + if (colorTable) { + for (a = 0, ct = colorTable; a < ncolors; a++, ct++) + if (*ct) { + for (b = 0, cts = *ct; b <= NKEYS; b++, cts++) + if (*cts) + free(*cts); + free(*ct); + } + free(colorTable); + } +} + + +/* + * Intialize the xpmInternAttrib pointers to Null to know + * which ones must be freed later on. + */ + +xpmInitInternAttrib(attrib) + xpmInternAttrib *attrib; +{ + attrib->ncolors = 0; + attrib->colorTable = NULL; + attrib->pixelindex = NULL; + attrib->xcolors = NULL; + attrib->colorStrings = NULL; + attrib->mask_pixel = UNDEF_PIXEL; +} + + +/* + * Free the xpmInternAttrib pointers which have been allocated + */ + +xpmFreeInternAttrib(attrib) + xpmInternAttrib *attrib; +{ + unsigned int a, ncolors; + char **sptr; + + if (attrib->colorTable) + xpmFreeColorTable(attrib->colorTable, attrib->ncolors); + if (attrib->pixelindex) + free(attrib->pixelindex); + if (attrib->xcolors) + free(attrib->xcolors); + if (attrib->colorStrings) { + ncolors = attrib->ncolors; + for (a = 0, sptr = attrib->colorStrings; a < ncolors; a++, sptr++) + if (*sptr) + free(*sptr); + free(attrib->colorStrings); + } +} + + +/* + * Free array of extensions + */ +XpmFreeExtensions(extensions, nextensions) + XpmExtension *extensions; + int nextensions; +{ + unsigned int i, j, nlines; + XpmExtension *ext; + char **sptr; + + if (extensions) { + for (i = 0, ext = extensions; i < nextensions; i++, ext++) { + if (ext->name) + free(ext->name); + nlines = ext->nlines; + for (j = 0, sptr = ext->lines; j < nlines; j++, sptr++) + if (*sptr) + free(*sptr); + if (ext->lines) + free(ext->lines); + } + free(extensions); + } +} + + +/* + * Return the XpmAttributes structure size + */ + +XpmAttributesSize() +{ + return sizeof(XpmAttributes); +} + + +/* + * Free the XpmAttributes structure members + * but the structure itself + */ + +XpmFreeAttributes(attributes) + XpmAttributes *attributes; +{ + if (attributes) { + if (attributes->valuemask & XpmReturnPixels && attributes->pixels) { + free(attributes->pixels); + attributes->pixels = NULL; + attributes->npixels = 0; + } + if (attributes->valuemask & XpmInfos) { + if (attributes->colorTable) { + xpmFreeColorTable(attributes->colorTable, attributes->ncolors); + attributes->colorTable = NULL; + attributes->ncolors = 0; + } + if (attributes->hints_cmt) { + free(attributes->hints_cmt); + attributes->hints_cmt = NULL; + } + if (attributes->colors_cmt) { + free(attributes->colors_cmt); + attributes->colors_cmt = NULL; + } + if (attributes->pixels_cmt) { + free(attributes->pixels_cmt); + attributes->pixels_cmt = NULL; + } + if (attributes->pixels) { + free(attributes->pixels); + attributes->pixels = NULL; + } + } + if (attributes->valuemask & XpmReturnExtensions + && attributes->nextensions) { + XpmFreeExtensions(attributes->extensions, attributes->nextensions); + attributes->nextensions = 0; + attributes->extensions = NULL; + } + attributes->valuemask = 0; + } +} + + +/* + * Store into the XpmAttributes structure the required informations stored in + * the xpmInternAttrib structure. + */ + +xpmSetAttributes(attrib, attributes) + xpmInternAttrib *attrib; + XpmAttributes *attributes; +{ + if (attributes) { + if (attributes->valuemask & XpmReturnInfos) { + attributes->cpp = attrib->cpp; + attributes->ncolors = attrib->ncolors; + attributes->colorTable = attrib->colorTable; + + attrib->ncolors = 0; + attrib->colorTable = NULL; + } + attributes->width = attrib->width; + attributes->height = attrib->height; + attributes->valuemask |= XpmSize; + } +} + +#ifdef NEED_STRDUP + +/* + * in case strdup is not provided by the system here is one + * which does the trick + */ +char * +strdup (s1) + char *s1; +{ + char *s2; + int l = strlen(s1) + 1; + if (s2 = (char *) malloc(l)) + strncpy(s2, s1, l); + return s2; +} + +#endif diff --git a/src/xpm/parse.c b/src/xpm/parse.c new file mode 100644 index 0000000..560b719 --- /dev/null +++ b/src/xpm/parse.c @@ -0,0 +1,537 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* parse.c: * +* * +* XPM library * +* Parse an XPM file or array and store the found informations * +* in an an xpmInternAttrib structure which is returned. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + + +#include "xpmP.h" +#ifdef VMS +#include "sys$library:ctype.h" +#else +#include <ctype.h> +#endif + +LFUNC(ParseValues, int, (xpmData *data, unsigned int *width, + unsigned int *height, unsigned int *ncolors, + unsigned int *cpp, unsigned int *x_hotspot, + unsigned int *y_hotspot, unsigned int *hotspot, + unsigned int *extensions)); + +LFUNC(ParseColors, int, (xpmData *data, unsigned int ncolors, unsigned int cpp, + char ****colorTablePtr, xpmHashTable *hashtable)); + +LFUNC(ParsePixels, int, (xpmData *data, unsigned int width, + unsigned int height, unsigned int ncolors, + unsigned int cpp, char ***colorTable, + xpmHashTable *hashtable, unsigned int **pixels)); + +LFUNC(ParseExtensions, int, (xpmData *data, XpmExtension **extensions, + unsigned int *nextensions)); + +char *xpmColorKeys[] = +{ + "s", /* key #1: symbol */ + "m", /* key #2: mono visual */ + "g4", /* key #3: 4 grays visual */ + "g", /* key #4: gray visual */ + "c", /* key #5: color visual */ +}; + + +/* function call in case of error, frees only locally allocated variables */ +#undef RETURN +#define RETURN(status) \ + { if (colorTable) xpmFreeColorTable(colorTable, ncolors); \ + if (pixelindex) free(pixelindex); \ + if (hints_cmt) free(hints_cmt); \ + if (colors_cmt) free(colors_cmt); \ + if (pixels_cmt) free(pixels_cmt); \ + return(status); } + +/* + * This function parses an Xpm file or data and store the found informations + * in an an xpmInternAttrib structure which is returned. + */ +int +xpmParseData(data, attrib_return, attributes) + xpmData *data; + xpmInternAttrib *attrib_return; + XpmAttributes *attributes; +{ + /* variables to return */ + unsigned int width, height, ncolors, cpp; + unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0; + char ***colorTable = NULL; + unsigned int *pixelindex = NULL; + char *hints_cmt = NULL; + char *colors_cmt = NULL; + char *pixels_cmt = NULL; + + int ErrorStatus; + xpmHashTable hashtable; + + /* + * read values + */ + ErrorStatus = ParseValues(data, &width, &height, &ncolors, &cpp, + &x_hotspot, &y_hotspot, &hotspot, &extensions); + if (ErrorStatus != XpmSuccess) + return(ErrorStatus); + + /* + * store the hints comment line + */ + if (attributes && (attributes->valuemask & XpmReturnInfos)) + xpmGetCmt(data, &hints_cmt); + + /* + * init the hastable + */ + if (USE_HASHTABLE) { + ErrorStatus = xpmHashTableInit(&hashtable); + if (ErrorStatus != XpmSuccess) + return(ErrorStatus); + } + + /* + * read colors + */ + ErrorStatus = ParseColors(data, ncolors, cpp, &colorTable, &hashtable); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + /* + * store the colors comment line + */ + if (attributes && (attributes->valuemask & XpmReturnInfos)) + xpmGetCmt(data, &colors_cmt); + + /* + * read pixels and index them on color number + */ + ErrorStatus = ParsePixels(data, width, height, ncolors, cpp, colorTable, + &hashtable, &pixelindex); + + /* + * free the hastable + */ + if (USE_HASHTABLE) + xpmHashTableFree(&hashtable); + + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + /* + * store the pixels comment line + */ + if (attributes && (attributes->valuemask & XpmReturnInfos)) + xpmGetCmt(data, &pixels_cmt); + + /* + * parse extensions + */ + if (attributes && (attributes->valuemask & XpmReturnExtensions)) + if (extensions) { + ErrorStatus = ParseExtensions(data, &attributes->extensions, + &attributes->nextensions); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + } else { + attributes->extensions = NULL; + attributes->nextensions = 0; + } + + /* + * store found informations in the xpmInternAttrib structure + */ + attrib_return->width = width; + attrib_return->height = height; + attrib_return->cpp = cpp; + attrib_return->ncolors = ncolors; + attrib_return->colorTable = colorTable; + attrib_return->pixelindex = pixelindex; + + if (attributes) { + if (attributes->valuemask & XpmReturnInfos) { + attributes->hints_cmt = hints_cmt; + attributes->colors_cmt = colors_cmt; + attributes->pixels_cmt = pixels_cmt; + } + if (hotspot) { + attributes->x_hotspot = x_hotspot; + attributes->y_hotspot = y_hotspot; + attributes->valuemask |= XpmHotspot; + } + } + return (XpmSuccess); +} + +static int +ParseValues(data, width, height, ncolors, cpp, + x_hotspot, y_hotspot, hotspot, extensions) + xpmData *data; + unsigned int *width, *height, *ncolors, *cpp; + unsigned int *x_hotspot, *y_hotspot, *hotspot; + unsigned int *extensions; +{ + unsigned int l; + char buf[BUFSIZ]; + + /* + * read values: width, height, ncolors, chars_per_pixel + */ + if (!(xpmNextUI(data, width) && xpmNextUI(data, height) + && xpmNextUI(data, ncolors) && xpmNextUI(data, cpp))) + return(XpmFileInvalid); + + /* + * read optional information (hotspot and/or XPMEXT) if any + */ + l = xpmNextWord(data, buf); + if (l) { + *extensions = l == 6 && !strncmp("XPMEXT", buf, 6); + if (*extensions) + *hotspot = xpmNextUI(data, x_hotspot) + && xpmNextUI(data, y_hotspot); + else { + *hotspot = atoui(buf, l, x_hotspot) && xpmNextUI(data, y_hotspot); + l = xpmNextWord(data, buf); + *extensions = l == 6 && !strncmp("XPMEXT", buf, 6); + } + } + return (XpmSuccess); +} + +static int +ParseColors(data, ncolors, cpp, colorTablePtr, hashtable) + xpmData *data; + unsigned int ncolors; + unsigned int cpp; + char ****colorTablePtr; /* Jee, that's something! */ + xpmHashTable *hashtable; +{ + unsigned int key, l, a, b; + unsigned int curkey; /* current color key */ + unsigned int lastwaskey; /* key read */ + char buf[BUFSIZ]; + char curbuf[BUFSIZ]; /* current buffer */ + char ***ct, **cts, **sptr, *s; + char ***colorTable; + int ErrorStatus; + + colorTable = (char ***) calloc(ncolors, sizeof(char **)); + if (!colorTable) + return(XpmNoMemory); + + for (a = 0, ct = colorTable; a < ncolors; a++, ct++) { + xpmNextString(data); /* skip the line */ + cts = *ct = (char **) calloc((NKEYS + 1), sizeof(char *)); + if (!cts) { + xpmFreeColorTable(colorTable, ncolors); + return(XpmNoMemory); + } + + /* + * read pixel value + */ + *cts = (char *) malloc(cpp + 1); /* + 1 for null terminated */ + if (!*cts) { + xpmFreeColorTable(colorTable, ncolors); + return(XpmNoMemory); + } + for (b = 0, s = *cts; b < cpp; b++, s++) + *s = xpmGetC(data); + *s = '\0'; + + /* + * store the string in the hashtable with its color index number + */ + if (USE_HASHTABLE) { + ErrorStatus = xpmHashIntern(hashtable, *cts, HashAtomData((long)a)); + if (ErrorStatus != XpmSuccess) { + xpmFreeColorTable(colorTable, ncolors); + return(ErrorStatus); + } + } + + /* + * read color keys and values + */ + curkey = 0; + lastwaskey = 0; + while (l = xpmNextWord(data, buf)) { + if (!lastwaskey) { + for (key = 0, sptr = xpmColorKeys; key < NKEYS; key++, sptr++) + if ((strlen(*sptr) == l) && (!strncmp(*sptr, buf, l))) + break; + } + if (!lastwaskey && key < NKEYS) { /* open new key */ + if (curkey) { /* flush string */ + s = cts[curkey] = (char *) malloc(strlen(curbuf) + 1); + if (!s) { + xpmFreeColorTable(colorTable, ncolors); + return(XpmNoMemory); + } + strcpy(s, curbuf); + } + curkey = key + 1; /* set new key */ + *curbuf = '\0'; /* reset curbuf */ + lastwaskey = 1; + } else { + if (!curkey) { /* key without value */ + xpmFreeColorTable(colorTable, ncolors); + return(XpmFileInvalid); + } + if (!lastwaskey) + strcat(curbuf, " "); /* append space */ + buf[l] = '\0'; + strcat(curbuf, buf); /* append buf */ + lastwaskey = 0; + } + } + if (!curkey) { /* key without value */ + xpmFreeColorTable(colorTable, ncolors); + return(XpmFileInvalid); + } + s = cts[curkey] = (char *) malloc(strlen(curbuf) + 1); + if (!s) { + xpmFreeColorTable(colorTable, ncolors); + return(XpmNoMemory); + } + strcpy(s, curbuf); + } + *colorTablePtr = colorTable; + return(XpmSuccess); +} + +static int +ParsePixels(data, width, height, ncolors, cpp, colorTable, hashtable, pixels) + xpmData *data; + unsigned int width; + unsigned int height; + unsigned int ncolors; + unsigned int cpp; + char ***colorTable; + xpmHashTable *hashtable; + unsigned int **pixels; +{ + unsigned int *iptr, *iptr2; + unsigned int a, x, y; + + iptr2 = (unsigned int *) malloc(sizeof(unsigned int) * width * height); + if (!iptr2) + return(XpmNoMemory); + + iptr = iptr2; + + switch (cpp) { + + case (1): /* Optimize for single character colors */ + { + unsigned short colidx[256]; + + bzero(colidx, 256 * sizeof(short)); + for (a = 0; a < ncolors; a++) + colidx[ colorTable[a][0][0] ] = a + 1; + + for (y = 0; y < height; y++) + { + xpmNextString(data); + for (x = 0; x < width; x++, iptr++) + { + int idx = colidx[xpmGetC(data)]; + if ( idx != 0 ) + *iptr = idx - 1; + else { + free(iptr2); + return(XpmFileInvalid); + } + } + } + } + break; + + case (2): /* Optimize for double character colors */ + { + unsigned short cidx[256][256]; + + bzero(cidx, 256*256 * sizeof(short)); + for (a = 0; a < ncolors; a++) + cidx [ colorTable[a][0][0] ][ colorTable[a][0][1] ] = a + 1; + + for (y = 0; y < height; y++) + { + xpmNextString(data); + for (x = 0; x < width; x++, iptr++) + { + int cc1 = xpmGetC(data); + int idx = cidx[cc1][ xpmGetC(data) ]; + if ( idx != 0 ) + *iptr = idx - 1; + else { + free(iptr2); + return(XpmFileInvalid); + } + } + } + } + break; + + default : /* Non-optimized case of long color names */ + { + char *s; + char buf[BUFSIZ]; + + buf[cpp] = '\0'; + if (USE_HASHTABLE) { + xpmHashAtom *slot; + + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++, iptr++) { + for (a = 0, s = buf; a < cpp; a++, s++) + *s = xpmGetC(data); + slot = xpmHashSlot(hashtable, buf); + if (!*slot) { /* no color matches */ + free(iptr2); + return(XpmFileInvalid); + } + *iptr = HashColorIndex(slot); + } + } + } else { + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++, iptr++) { + for (a = 0, s = buf; a < cpp; a++, s++) + *s = xpmGetC(data); + for (a = 0; a < ncolors; a++) + if (!strcmp(colorTable[a][0], buf)) + break; + if (a == ncolors) { /* no color matches */ + free(iptr2); + return(XpmFileInvalid); + } + *iptr = a; + } + } + } + } + break; + } + *pixels = iptr2; + return (XpmSuccess); +} + +static int +ParseExtensions(data, extensions, nextensions) + xpmData *data; + XpmExtension **extensions; + unsigned int *nextensions; +{ + XpmExtension *exts = NULL, *ext; + unsigned int num = 0; + unsigned int nlines, a, l, notstart, notend = 0; + int status; + char *string, *s, *s2, **sp; + + xpmNextString(data); + exts = (XpmExtension *) malloc(sizeof(XpmExtension)); + /* get the whole string */ + status = xpmGetString(data, &string, &l); + if (status != XpmSuccess) { + free(exts); + return(status); + } + /* look for the key word XPMEXT, skip lines before this */ + while ((notstart = strncmp("XPMEXT", string, 6)) + && (notend = strncmp("XPMENDEXT", string, 9))) { + free(string); + xpmNextString(data); + status = xpmGetString(data, &string, &l); + if (status != XpmSuccess) { + free(exts); + return(status); + } + } + if (!notstart) + notend = strncmp("XPMENDEXT", string, 9); + while (!notstart && notend) { + /* there starts an extension */ + ext = (XpmExtension *) realloc(exts, (num + 1) * sizeof(XpmExtension)); + if (!ext) { + free(string); + XpmFreeExtensions(exts, num); + return(XpmNoMemory); + } + exts = ext; + ext += num; + /* skip whitespace and store its name */ + s2 = s = string + 6; + while (isspace(*s2)) + s2++; + a = s2 - s; + ext->name = (char *) malloc(l - a - 6); + if (!ext->name) { + free(string); + ext->lines = NULL; + ext->nlines = 0; + XpmFreeExtensions(exts, num + 1); + return(XpmNoMemory); + } + strncpy(ext->name, s + a, l - a - 6); + free(string); + /* now store the related lines */ + xpmNextString(data); + status = xpmGetString(data, &string, &l); + if (status != XpmSuccess) { + ext->lines = NULL; + ext->nlines = 0; + XpmFreeExtensions(exts, num + 1); + return(status); + } + ext->lines = (char **) malloc(sizeof(char *)); + nlines = 0; + while ((notstart = strncmp("XPMEXT", string, 6)) + && (notend = strncmp("XPMENDEXT", string, 9))) { + sp = (char **) realloc(ext->lines, (nlines + 1) * sizeof(char *)); + if (!sp) { + free(string); + ext->nlines = nlines; + XpmFreeExtensions(exts, num + 1); + return(XpmNoMemory); + } + ext->lines = sp; + ext->lines[nlines] = string; + nlines++; + xpmNextString(data); + status = xpmGetString(data, &string, &l); + if (status != XpmSuccess) { + ext->nlines = nlines; + XpmFreeExtensions(exts, num + 1); + return(status); + } + } + if (!nlines) { + free(ext->lines); + ext->lines = NULL; + } + ext->nlines = nlines; + num++; + } + if (!num) { + free(string); + free(exts); + exts = NULL; + } else if (!notend) + free(string); + *nextensions = num; + *extensions = exts; + return(XpmSuccess); +} diff --git a/src/xpm/rename b/src/xpm/rename new file mode 100755 index 0000000..a767d5e --- /dev/null +++ b/src/xpm/rename @@ -0,0 +1,24 @@ +#!/bin/sh +# rename is provided to easily update code using sed-command files + +USAGE='rename sed-command-file file1 file2... + apply all sed-command-file to the files file1 file2 +' + +if test "$1" = '-?'; then echo "$USAGE";exit 1;fi +commands=$1 +shift + +for i in $* +do if test -f $i + then echo -n "$i: " + echo -n "." + sed -f $commands $i > /tmp/rename.sed.$$; + if test ! -s /tmp/rename.sed.$$; then rm /tmp/rename.sed.$$; exit 1;fi + if cmp /tmp/rename.sed.$$ $i >/dev/null; then echo + else cp $i $i.BAK; cp /tmp/rename.sed.$$ $i; echo " modified." + fi + fi +done + +rm -f /tmp/rename.sed.$$ /tmp/rename.sed.$$.org diff --git a/src/xpm/rgb.c b/src/xpm/rgb.c new file mode 100644 index 0000000..6694a60 --- /dev/null +++ b/src/xpm/rgb.c @@ -0,0 +1,136 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* rgb.c: * +* * +* XPM library * +* Rgb file utilities * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * Part of this code has been taken from the ppmtoxpm.c file written by Mark + * W. Snitily but has been modified for my special need + */ + +#include "xpmP.h" +#ifdef VMS +#include "sys$library:ctype.h" +#include "sys$library:string.h" +#else +#include <ctype.h> +#if defined(SYSV) || defined(SVR4) +#include <string.h> +#else +#include <strings.h> +#endif +#endif + +/* + * Read a rgb text file. It stores the rgb values (0->65535) + * and the rgb mnemonics (malloc'ed) into the "rgbn" array. Returns the + * number of entries stored. + */ +int +xpmReadRgbNames(rgb_fname, rgbn) + char *rgb_fname; + xpmRgbName rgbn[]; + +{ + FILE *rgbf; + int i, items, red, green, blue; + char line[512], name[512], *rgbname, *n, *m; + xpmRgbName *rgb; + + /* Open the rgb text file. Abort if error. */ + if ((rgbf = fopen(rgb_fname, "r")) == NULL) + return 0; + + /* Loop reading each line in the file. */ + for (i = 0, rgb = rgbn; fgets(line, sizeof(line), rgbf); i++, rgb++) { + + /* Quit if rgb text file is too large. */ + if (i == MAX_RGBNAMES) { + /* Too many entries in rgb text file, give up here */ + break; + } + /* Read the line. Skip silently if bad. */ + items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name); + if (items != 4) { + i--; + continue; + } + + /* + * Make sure rgb values are within 0->255 range. Skip silently if + * bad. + */ + if (red < 0 || red > 0xFF || + green < 0 || green > 0xFF || + blue < 0 || blue > 0xFF) { + i--; + continue; + } + /* Allocate memory for ascii name. If error give up here. */ + if (!(rgbname = (char *) malloc(strlen(name) + 1))) + break; + + /* Copy string to ascii name and lowercase it. */ + for (n = name, m = rgbname; *n; n++) + *m++ = isupper(*n) ? tolower(*n) : *n; + *m = '\0'; + + /* Save the rgb values and ascii name in the array. */ + rgb->r = red * 257; /* 65535/255 = 257 */ + rgb->g = green * 257; + rgb->b = blue * 257; + rgb->name = rgbname; + } + + fclose(rgbf); + + /* Return the number of read rgb names. */ + return i < 0 ? 0 : i; +} + +/* + * Return the color name corresponding to the given rgb values + */ +char * +xpmGetRgbName(rgbn, rgbn_max, red, green, blue) + xpmRgbName rgbn[]; /* rgb mnemonics from rgb text file */ +int rgbn_max; /* number of rgb mnemonics in table */ +int red, green, blue; /* rgb values */ + +{ + int i; + xpmRgbName *rgb; + + /* + * Just perform a dumb linear search over the rgb values of the color + * mnemonics. One could speed things up by sorting the rgb values and + * using a binary search, or building a hash table, etc... + */ + for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++) + if (red == rgb->r && green == rgb->g && blue == rgb->b) + return rgb->name; + + /* if not found return NULL */ + return NULL; +} + +/* + * Free the strings which have been malloc'ed in xpmReadRgbNames + */ +void +xpmFreeRgbNames(rgbn, rgbn_max) + xpmRgbName rgbn[]; +int rgbn_max; + +{ + int i; + xpmRgbName *rgb; + + for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++) + free(rgb->name); +} diff --git a/src/xpm/scan.c b/src/xpm/scan.c new file mode 100644 index 0000000..2cee34c --- /dev/null +++ b/src/xpm/scan.c @@ -0,0 +1,567 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* scan.c: * +* * +* XPM library * +* Scanning utility for XPM file format * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include "xpmP.h" + +#define MAXPRINTABLE 93 /* number of printable ascii chars + * minus \ and " for string compat + * and / to avoid comment conflicts. */ + +static char *printable = +" .XoO+@#$%&*=-;:?>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\ +ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; + + /* + * printable begin with a space, so in most case, due to my algorithm, when + * the number of different colors is less than MAXPRINTABLE, it will give a + * char follow by "nothing" (a space) in the readable xpm file + */ + + +typedef struct { + Pixel *pixels; + unsigned int *pixelindex; + unsigned int size; + unsigned int ncolors; + unsigned int mask_pixel; /* whether there is or not */ +} PixelsMap; + +LFUNC(storePixel, int, (Pixel pixel, PixelsMap * pmap, + unsigned int *index_return)); + +LFUNC(storeMaskPixel, int, (Pixel pixel, PixelsMap * pmap, + unsigned int *index_return)); + +LFUNC(GetImagePixels, int, (XImage * image, unsigned int width, + unsigned int height, PixelsMap * pmap)); + +LFUNC(GetImagePixels32, int, (XImage * image, unsigned int width, + unsigned int height, PixelsMap * pmap)); + +LFUNC(GetImagePixels16, int, (XImage * image, unsigned int width, + unsigned int height, PixelsMap * pmap)); + +LFUNC(GetImagePixels8, int, (XImage * image, unsigned int width, + unsigned int height, PixelsMap * pmap)); + +LFUNC(GetImagePixels1, int, (XImage * image, unsigned int width, + unsigned int height, PixelsMap * pmap, + int (*storeFunc) ())); + +/* + * This function stores the given pixel in the given arrays which are grown + * if not large enough. + */ +static int +storePixel(pixel, pmap, index_return) + Pixel pixel; + PixelsMap *pmap; + unsigned int *index_return; +{ + register unsigned int a; + register Pixel *p; + register unsigned int ncolors; + + if (*index_return) { /* this is a transparent pixel! */ + *index_return = 0; + return 0; + } + ncolors = pmap->ncolors; + p = &(pmap->pixels[pmap->mask_pixel]); + for (a = pmap->mask_pixel; a < ncolors; a++, p++) + if (*p == pixel) + break; + if (a == ncolors) { + if (ncolors > pmap->size) { + + pmap->size *= 2; + p = (Pixel *) realloc(pmap->pixels, sizeof(Pixel) * pmap->size); + if (!p) + return (1); + pmap->pixels = p; + + } + (pmap->pixels)[ncolors] = pixel; + pmap->ncolors++; + } + *index_return = a; + return 0; +} + +static int +storeMaskPixel(pixel, pmap, index_return) + Pixel pixel; + PixelsMap *pmap; + unsigned int *index_return; +{ + if (!pixel) { + if (!pmap->ncolors) { + pmap->ncolors = 1; + (pmap->pixels)[0] = 0; + pmap->mask_pixel = 1; + } + *index_return = 1; + } else + *index_return = 0; + return 0; +} + +/* function call in case of error, frees only locally allocated variables */ +#undef RETURN +#define RETURN(status) \ + { if (pmap.pixelindex) free(pmap.pixelindex); \ + if (pmap.pixels) free(pmap.pixels); \ + if (xcolors) free(xcolors); \ + if (colorStrings) { \ + for (a = 0; a < pmap.ncolors; a++) \ + if (colorStrings[a]) \ + free(colorStrings[a]); \ + free(colorStrings); \ + } \ + return(status); } + +/* + * This function scans the given image and stores the found informations in + * the xpmInternAttrib structure which is returned. + */ +int +xpmScanImage(display, image, shapeimage, attributes, attrib) + Display *display; + XImage *image; + XImage *shapeimage; + XpmAttributes *attributes; + xpmInternAttrib *attrib; + +{ + /* variables stored in the XpmAttributes structure */ + Colormap colormap; + unsigned int cpp; + + /* variables to return */ + PixelsMap pmap; + char **colorStrings = NULL; + XColor *xcolors = NULL; + int ErrorStatus; + + /* calculation variables */ + unsigned int width = 0; + unsigned int height = 0; + unsigned int cppm; /* minimum chars per pixel */ + unsigned int a, b, c; + register char *s; + + /* initialize pmap */ + pmap.pixels = NULL; + pmap.pixelindex = NULL; + pmap.size = 256; /* should be enough most of the time */ + pmap.ncolors = 0; + pmap.mask_pixel = 0; + + /* + * get geometry + */ + if (image) { + width = image->width; + height = image->height; + } else if (shapeimage) { + width = shapeimage->width; + height = shapeimage->height; + } + + /* + * retrieve information from the XpmAttributes + */ + if (attributes && attributes->valuemask & XpmColormap) + colormap = attributes->colormap; + else + colormap = DefaultColormap(display, DefaultScreen(display)); + + if (attributes && (attributes->valuemask & XpmCharsPerPixel + || attributes->valuemask & XpmInfos)) + cpp = attributes->cpp; + else + cpp = 0; + + pmap.pixelindex = + (unsigned int *) calloc(width * height, sizeof(unsigned int)); + if (!pmap.pixelindex) + RETURN(XpmNoMemory); + + pmap.pixels = (Pixel *) malloc(sizeof(Pixel) * pmap.size); + if (!pmap.pixels) + RETURN(XpmNoMemory); + + /* + * scan shape mask if any + */ + if (shapeimage) { + ErrorStatus = GetImagePixels1(shapeimage, width, height, &pmap, + storeMaskPixel); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + } + + /* + * scan the image data + * + * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use optimized + * functions, otherwise use slower but sure general one. + * + */ + + if (image) { + if (image->depth == 1) + ErrorStatus = GetImagePixels1(image, width, height, &pmap, + storePixel); + else if (image->bits_per_pixel == 8) + ErrorStatus = GetImagePixels8(image, width, height, &pmap); + else if (image->bits_per_pixel == 16) + ErrorStatus = GetImagePixels16(image, width, height, &pmap); + else if (image->bits_per_pixel == 32) + ErrorStatus = GetImagePixels32(image, width, height, &pmap); + else + ErrorStatus = GetImagePixels(image, width, height, &pmap); + + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + } + + /* + * get rgb values and a string of char for each color + */ + + xcolors = (XColor *) malloc(sizeof(XColor) * pmap.ncolors); + if (!xcolors) + RETURN(XpmNoMemory); + colorStrings = (char **) calloc(pmap.ncolors, sizeof(char *)); + if (!colorStrings) + RETURN(XpmNoMemory); + + for (cppm = 1, c = MAXPRINTABLE; pmap.ncolors > c; cppm++) + c *= MAXPRINTABLE; + if (cpp < cppm) + cpp = cppm; + + for (a = 0; a < pmap.ncolors; a++) { + if (!(s = colorStrings[a] = (char *) malloc(cpp))) + RETURN(XpmNoMemory); + *s++ = printable[c = a % MAXPRINTABLE]; + for (b = 1; b < cpp; b++, s++) + *s = printable[c = ((a - c) / MAXPRINTABLE) % MAXPRINTABLE]; + xcolors[a].pixel = pmap.pixels[a]; + } + + XQueryColors(display, colormap, xcolors, pmap.ncolors); + + /* + * store found informations in the xpmInternAttrib structure + */ + attrib->width = width; + attrib->height = height; + attrib->cpp = cpp; + attrib->ncolors = pmap.ncolors; + attrib->mask_pixel = pmap.mask_pixel ? 0 : UNDEF_PIXEL; + attrib->pixelindex = pmap.pixelindex; + attrib->xcolors = xcolors; + attrib->colorStrings = colorStrings; + + free(pmap.pixels); + return (XpmSuccess); +} + + + +/* + * The functions below are written from X11R5 MIT's code (XImUtil.c) + * + * The idea is to have faster functions than the standard XGetPixel function + * to scan the image data. Indeed we can speed up things by suppressing tests + * performed for each pixel. We do exactly the same tests but at the image + * level. Assuming that we use only ZPixmap images. + */ + +static unsigned long Const low_bits_table[] = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, + 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, + 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, + 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, + 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, + 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, + 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, + 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, + 0xffffffff +}; + +/* + * Default method to scan pixels of a Z image data structure. + * The algorithm used is: + * + * copy the source bitmap_unit or Zpixel into temp + * normalize temp if needed + * extract the pixel bits into return value + * + */ + +static int +GetImagePixels(image, width, height, pmap) + XImage *image; + unsigned int width; + unsigned int height; + PixelsMap *pmap; +{ + register char *src; + register char *dst; + register unsigned int *iptr; + register char *data; + register int x, y, i; + int bits, depth, ibu, ibpp; + unsigned long lbt; + Pixel pixel, px; + + data = image->data; + iptr = pmap->pixelindex; + depth = image->depth; + lbt = low_bits_table[depth]; + ibpp = image->bits_per_pixel; + if (image->depth == 1) { + ibu = image->bitmap_unit; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + src = &data[XYINDEX(x, y, image)]; + dst = (char *) &pixel; + pixel = 0; + for (i = ibu >> 3; --i >= 0;) + *dst++ = *src++; + XYNORMALIZE(&pixel, image); + bits = x % ibu; + pixel = ((((char *) &pixel)[bits >> 3]) >> (bits & 7)) & 1; + if (ibpp != depth) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + } else { + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + src = &data[ZINDEX(x, y, image)]; + dst = (char *) &px; + px = 0; + for (i = (ibpp + 7) >> 3; --i >= 0;) + *dst++ = *src++; + ZNORMALIZE(&px, image); + pixel = 0; + for (i = sizeof(unsigned long); --i >= 0;) + pixel = (pixel << 8) | ((unsigned char *) &px)[i]; + if (ibpp == 4) { + if (x & 1) + pixel >>= 4; + else + pixel &= 0xf; + } + if (ibpp != depth) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + } + return(XpmSuccess); +} + +/* + * scan pixels of a 32-bits Z image data structure + */ + +#ifndef WORD64 +static unsigned long byteorderpixel = MSBFirst << 24; + +#endif + +static int +GetImagePixels32(image, width, height, pmap) + XImage *image; + unsigned int width; + unsigned int height; + PixelsMap *pmap; +{ + register unsigned char *addr; + register unsigned char *data; + register unsigned int *iptr; + register int x, y; + unsigned long lbt; + Pixel pixel; + int depth; + + data = (unsigned char *) image->data; + iptr = pmap->pixelindex; + depth = image->depth; + lbt = low_bits_table[depth]; +#ifndef WORD64 + if (*((char *) &byteorderpixel) == image->byte_order) { + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + pixel = *((unsigned long *)addr); + if (depth != 32) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + } else +#endif + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + pixel = ((unsigned long) addr[0] << 24 | + (unsigned long) addr[1] << 16 | + (unsigned long) addr[2] << 8 | + addr[4]); + if (depth != 32) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + pixel = (addr[0] | + (unsigned long) addr[1] << 8 | + (unsigned long) addr[2] << 16 | + (unsigned long) addr[3] << 24); + if (depth != 32) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + return(XpmSuccess); +} + +/* + * scan pixels of a 16-bits Z image data structure + */ + +static int +GetImagePixels16(image, width, height, pmap) + XImage *image; + unsigned int width; + unsigned int height; + PixelsMap *pmap; +{ + register unsigned char *addr; + register unsigned char *data; + register unsigned int *iptr; + register int x, y; + unsigned long lbt; + Pixel pixel; + int depth; + + data = (unsigned char *) image->data; + iptr = pmap->pixelindex; + depth = image->depth; + lbt = low_bits_table[depth]; + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX16(x, y, image)]; + pixel = addr[0] << 8 | addr[1]; + if (depth != 16) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX16(x, y, image)]; + pixel = addr[0] | addr[1] << 8; + if (depth != 16) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + return(XpmSuccess); +} + +/* + * scan pixels of a 8-bits Z image data structure + */ + +static int +GetImagePixels8(image, width, height, pmap) + XImage *image; + unsigned int width; + unsigned int height; + PixelsMap *pmap; +{ + register unsigned int *iptr; + register unsigned char *data; + register int x, y; + unsigned long lbt; + Pixel pixel; + int depth; + + data = (unsigned char *) image->data; + iptr = pmap->pixelindex; + depth = image->depth; + lbt = low_bits_table[depth]; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + pixel = data[ZINDEX8(x, y, image)]; + if (depth != 8) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + return(XpmSuccess); +} + +/* + * scan pixels of a 1-bit depth Z image data structure + */ + +static int +GetImagePixels1(image, width, height, pmap, storeFunc) + XImage *image; + unsigned int width; + unsigned int height; + PixelsMap *pmap; + int (*storeFunc) (); + +{ + register unsigned int *iptr; + register int x, y; + register char *data; + Pixel pixel; + + if (image->byte_order != image->bitmap_bit_order) + return(GetImagePixels(image, width, height, pmap)); + else { + data = image->data; + iptr = pmap->pixelindex; + if (image->bitmap_bit_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + pixel = (data[ZINDEX1(x, y, image)] & (0x80 >> (x & 7))) + ? 1 : 0; + if ((*storeFunc) (pixel, pmap, iptr)) + return (XpmNoMemory); + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + pixel = (data[ZINDEX1(x, y, image)] & (1 << (x & 7))) + ? 1 : 0; + if ((*storeFunc) (pixel, pmap, iptr)) + return (XpmNoMemory); + } + } + return(XpmSuccess); +} diff --git a/src/xpm/sxpm.c b/src/xpm/sxpm.c new file mode 100644 index 0000000..9ee3ad3 --- /dev/null +++ b/src/xpm/sxpm.c @@ -0,0 +1,580 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* sxpm.c: * +* * +* Show XPM File program * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifdef VMS +#include "decw$include:Xlib.h" +#include "decw$include:Intrinsic.h" +#include "decw$include:Shell.h" +#include "decw$include:shape.h" +#else +#include <X11/StringDefs.h> +#include <X11/Intrinsic.h> +#include <X11/Shell.h> +#include <X11/extensions/shape.h> +#endif + +#include "xpm.h" + +#ifdef Debug +/* memory leak control tool */ +#include <mnemosyne.h> +#endif + +/* XPM */ +/* plaid pixmap */ +static char *plaid[] = +{ +/* width height ncolors chars_per_pixel */ + "22 22 4 2 XPMEXT", +/* colors */ + " c red m white s light_color", + "Y c green m black s lines_in_mix", + "+ c yellow m white s lines_in_dark", + "x m black s dark_color", +/* pixels */ + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + "Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x ", + "x x x x x x x x x x x x x x x x x x x x x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x ", +"bullshit", +"XPMEXT ext1 data1", +"XPMEXT ext2", +"data2_1", +"data2_2", +"XPMEXT", +"foo", +"", +"XPMEXT ext3", +"data3", +"XPMENDEXT" +}; + +#define win XtWindow(topw) +#define dpy XtDisplay(topw) +#define screen XtScreen(topw) +#define root XRootWindowOfScreen(screen) +#define xrdb XtDatabase(dpy) +static Colormap colormap; + +void Usage(); +void ErrorMessage(); +void Punt(); +void kinput(); + +#define IWIDTH 50 +#define IHEIGHT 50 + +typedef struct _XpmIcon { + Pixmap pixmap; + Pixmap mask; + XpmAttributes attributes; +} XpmIcon; + +static char **command; +static Widget topw; +static XpmIcon view, icon; +static XrmOptionDescRec options[] = { + {"-hints", ".hints", XrmoptionNoArg, (XtPointer) "True"}, + {"-icon", ".icon", XrmoptionSepArg, (XtPointer) NULL}, +}; + +main(argc, argv) + int argc; + char **argv; +{ + int ErrorStatus; + unsigned int verbose = 0; + unsigned int stdinf = 1; + unsigned int stdoutf = 0; + unsigned int nod = 0; + unsigned int incResize = 0; + unsigned int resize = 0; + unsigned int w_rtn; + unsigned int h_rtn; + char *input = NULL; + char *output = NULL; + char *iconFile = NULL; + unsigned int numsymbols = 0; + XpmColorSymbol symbols[10]; + char *stype; + XrmValue val; + unsigned long valuemask = 0; + int n; + Arg args[3]; + +#ifdef Debug2 + char **data; + +#endif + + topw = XtInitialize(argv[0], "Sxpm", + options, XtNumber(options), &argc, argv); + + if (!topw) { + fprintf(stderr, "Sxpm Error... [ Undefined DISPLAY ]\n"); + exit(1); + } + + colormap = XDefaultColormapOfScreen(screen); + + /* + * geometry management + */ + + if (XrmGetResource(xrdb, NULL, "sxpm.geometry", &stype, &val) + || XrmGetResource(xrdb, NULL, "Sxpm.geometry", &stype, &val)) { + + int flags; + int x_rtn; + int y_rtn; + char *geo = NULL; + + geo = (char *) val.addr; + flags = XParseGeometry(geo, &x_rtn, &y_rtn, + (unsigned int *) &w_rtn, + (unsigned int *) &h_rtn); + if (!((WidthValue & flags) && (HeightValue & flags))) + resize = 1; + } else + resize = 1; + + n = 0; + if (resize) { + w_rtn = 0; + h_rtn = 0; + XtSetArg(args[n], XtNwidth, 1); + n++; + XtSetArg(args[n], XtNheight, 1); + n++; + } + XtSetArg(args[n], XtNmappedWhenManaged, False); + n++; + XtSetValues(topw, args, n); + + if ((XrmGetResource(xrdb, "sxpm.hints", "", &stype, &val) + || XrmGetResource(xrdb, "Sxpm.hints", "", &stype, &val)) + && !strcmp((char *) val.addr, "True")) { + /* gotcha */ + incResize = 1; + resize = 1; + } + + /* + * icon management + */ + + if (XrmGetResource(xrdb, "sxpm.icon", "", &stype, &val) || + XrmGetResource(xrdb, "Sxpm.icon", "", &stype, &val)) { + iconFile = (char *) val.addr; + } + if (iconFile) { + + XColor color, junk; + Pixel bpix; + Window iconW; + + if (XAllocNamedColor(dpy, colormap, "black", &color, &junk)) + bpix = color.pixel; + else + bpix = XBlackPixelOfScreen(screen); + + iconW = XCreateSimpleWindow(dpy, root, 0, 0, + IWIDTH, IHEIGHT, 1, bpix, bpix); + + icon.attributes.valuemask = XpmReturnPixels; + ErrorStatus = XpmReadFileToPixmap(dpy, root, iconFile, &icon.pixmap, + &icon.mask, &icon.attributes); + ErrorMessage(ErrorStatus, "Icon"); + + XSetWindowBackgroundPixmap(dpy, iconW, icon.pixmap); + + n = 0; + XtSetArg(args[n], XtNbackground, bpix); + n++; + XtSetArg(args[n], XtNiconWindow, iconW); + n++; + XtSetValues(topw, args, n); + } + + /* + * arguments parsing + */ + + command = argv; + for (n = 1; n < argc; n++) { + if (strncmp(argv[n], "-plaid", 3) == 0) { + stdinf = 0; + continue; + } + if (argv[n][0] != '-') { + stdinf = 0; + input = argv[n]; + continue; + } + if ((strlen(argv[n]) == 1) && (argv[n][0] == '-')) + /* stdin */ + continue; + if (strncmp(argv[n], "-o", 2) == 0) { + if (n < argc - 1) { + if ((strlen(argv[n + 1]) == 1) && (argv[n + 1][0] == '-')) + stdoutf = 1; + else + output = argv[n + 1]; + n++; + continue; + } else + Usage(); + } + if (strncmp(argv[n], "-nod", 2) == 0) { + nod = 1; + continue; + } + if (strncmp(argv[n], "-s", 2) == 0) { + if (n < argc - 2) { + valuemask |= XpmColorSymbols; + symbols[numsymbols].name = argv[++n]; + symbols[numsymbols++].value = argv[++n]; + continue; + } else + Usage(); + } + if (strncmp(argv[n], "-p", 2) == 0) { + if (n < argc - 2) { + valuemask |= XpmColorSymbols; + symbols[numsymbols].name = argv[++n]; + symbols[numsymbols].value = NULL; + symbols[numsymbols++].pixel = atol(argv[++n]); + continue; + } + } + if (strcmp(argv[n], "-closecolors") == 0) { + valuemask |= XpmCloseness; + view.attributes.closeness = 40000; + continue; + } + if (strncmp(argv[n], "-rgb", 3) == 0) { + if (n < argc - 1) { + valuemask |= XpmRgbFilename; + view.attributes.rgb_fname = argv[++n]; + continue; + } else + Usage(); + + } + if (strncmp(argv[n], "-v", 2) == 0) { + verbose = 1; + continue; + } + if (strncmp(argv[n], "-c", 2) == 0) { + valuemask |= XpmColormap; + continue; + } + Usage(); + } + + XtRealizeWidget(topw); + if (valuemask & XpmColormap) { + colormap = XCreateColormap(dpy, win, + DefaultVisual(dpy, DefaultScreen(dpy)), + AllocNone); + view.attributes.colormap = colormap; + XSetWindowColormap(dpy, win, colormap); + } + view.attributes.colorsymbols = symbols; + view.attributes.numsymbols = numsymbols; + view.attributes.valuemask = valuemask; + +#ifdef Debug2 + /* this is just to test the XpmCreateDataFromPixmap function */ + + view.attributes.valuemask |= XpmReturnPixels; + view.attributes.valuemask |= XpmReturnExtensions; + ErrorStatus = XpmCreatePixmapFromData(dpy, win, plaid, + &view.pixmap, &view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "Plaid"); + + ErrorStatus = XpmCreateDataFromPixmap(dpy, &data, view.pixmap, view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "Data"); + if (verbose && view.attributes.nextensions) { + unsigned int i, j; + for (i = 0; i < view.attributes.nextensions; i++) { + fprintf(stderr, "Xpm extension : %s\n", + view.attributes.extensions[i].name); + for (j = 0; j < view.attributes.extensions[i].nlines; j++) + fprintf(stderr, "\t\t%s\n", + view.attributes.extensions[i].lines[j]); + } + } + + XFreePixmap(dpy, view.pixmap); + if (view.mask) + XFreePixmap(dpy, view.mask); + + XFreeColors(dpy, colormap, + view.attributes.pixels, view.attributes.npixels, 0); + + XpmFreeAttributes(&view.attributes); + view.attributes.valuemask = valuemask; +#endif + + if (input || stdinf) { + view.attributes.valuemask |= XpmReturnInfos; + view.attributes.valuemask |= XpmReturnPixels; + view.attributes.valuemask |= XpmReturnExtensions; + +#ifdef Debug2 + free(data); + + ErrorStatus = XpmReadFileToData(input, &data); + ErrorMessage(ErrorStatus, "ReadFileToData"); + ErrorStatus = XpmCreatePixmapFromData(dpy, win, data, + &view.pixmap, &view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "CreatePixmapFromData"); + ErrorStatus = XpmWriteFileFromData("sxpmout.xpm", data); + ErrorMessage(ErrorStatus, "WriteFileFromData"); + free(data); +#endif + + ErrorStatus = XpmReadFileToPixmap(dpy, win, input, + &view.pixmap, &view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "Read"); + if (verbose && view.attributes.nextensions) { + unsigned int i, j; + for (i = 0; i < view.attributes.nextensions; i++) { + fprintf(stderr, "Xpm extension : %s\n", + view.attributes.extensions[i].name); + for (j = 0; j < view.attributes.extensions[i].nlines; j++) + fprintf(stderr, "\t\t%s\n", + view.attributes.extensions[i].lines[j]); + } + } + } else { +#ifdef Debug2 + ErrorStatus = XpmCreatePixmapFromData(dpy, win, data, + &view.pixmap, &view.mask, + &view.attributes); + free(data); +#else + ErrorStatus = XpmCreatePixmapFromData(dpy, win, plaid, + &view.pixmap, &view.mask, + &view.attributes); +#endif + ErrorMessage(ErrorStatus, "Plaid"); + } + if (output || stdoutf) { + ErrorStatus = XpmWriteFileFromPixmap(dpy, output, view.pixmap, + view.mask, &view.attributes); + ErrorMessage(ErrorStatus, "Write"); + } + if (!nod) { + + /* + * manage display if requested + */ + + XSizeHints size_hints; + char *xString = NULL; + + if (w_rtn && h_rtn + && ((w_rtn < view.attributes.width) + || h_rtn < view.attributes.height)) { + resize = 1; + } + if (resize) { + XtResizeWidget(topw, + view.attributes.width, view.attributes.height, 1); + } + if (incResize) { + size_hints.flags = USSize | PMinSize | PResizeInc; + size_hints.height = view.attributes.height; + size_hints.width = view.attributes.width; + size_hints.height_inc = view.attributes.height; + size_hints.width_inc = view.attributes.width; + } else + size_hints.flags = PMinSize; + + size_hints.min_height = view.attributes.height; + size_hints.min_width = view.attributes.width; + XSetWMNormalHints(dpy, win, &size_hints); + + if (input) { + xString = (char *) XtMalloc((sizeof(char) * strlen(input)) + 20); + sprintf(xString, "Sxpm: %s\0", input); + XStoreName(dpy, XtWindow(topw), xString); + XSetIconName(dpy, XtWindow(topw), xString); + } else if (stdinf) { + XStoreName(dpy, XtWindow(topw), "Sxpm: stdin"); + XSetIconName(dpy, XtWindow(topw), "Sxpm: stdin"); + } else { + XStoreName(dpy, XtWindow(topw), "Sxpm"); + XSetIconName(dpy, XtWindow(topw), "Sxpm"); + } + + XtAddEventHandler(topw, KeyPressMask, False, + (XtEventHandler) kinput, NULL); + XSetWindowBackgroundPixmap(dpy, win, view.pixmap); + + if (view.mask) + XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, + view.mask, ShapeSet); + + XClearWindow(dpy, win); + XMapWindow(dpy, win); + if (xString) + XtFree(xString); + XtMainLoop(); + } + Punt(0); +} + +void +Usage() +{ + fprintf(stderr, "\nUsage: %s [options...]\n", command[0]); + fprintf(stderr, "%s\n", "Where options are:"); + fprintf(stderr, "\n%s\n", + "[-d host:display] Display to connect to."); + fprintf(stderr, "%s\n", + "[-g geom] Geometry of window."); + fprintf(stderr, "%s\n", + "[-hints] Set ResizeInc for window."); + fprintf(stderr, "%s\n", + "[-icon filename] Set pixmap for iconWindow."); + fprintf(stderr, "%s\n", + "[-s symbol_name color_name] Overwrite color defaults."); + fprintf(stderr, "%s\n", + "[-p symbol_name pixel_value] Overwrite color defaults."); + fprintf(stderr, "%s\n", + "[-closecolors] Try to use `close' colors."); + fprintf(stderr, "%s\n", + "[-plaid] Read the included plaid pixmap."); + fprintf(stderr, "%s\n", + "[filename] Read from file 'filename', and from \ +standard"); + fprintf(stderr, "%s\n", + " input if 'filename' is '-'."); + fprintf(stderr, "%s\n", + "[-o filename] Write to file 'filename', and to \ +standard"); + fprintf(stderr, "%s\n", + " output if 'filename' is '-'."); + fprintf(stderr, "%s\n", + "[-nod] Don't display in window."); + fprintf(stderr, "%s\n", + "[-rgb filename] Search color names in the \ +rgb text file 'filename'."); + fprintf(stderr, "%s\n", + "[-c] Use a private colormap."); + fprintf(stderr, "%s\n\n", + "[-v] Verbose - print out extensions."); + fprintf(stderr, "%s\n\n", + "if no input is specified sxpm reads from standard input."); + exit(0); +} + + +void +ErrorMessage(ErrorStatus, tag) + int ErrorStatus; + char *tag; +{ + char *error = NULL; + char *warning = NULL; + + switch (ErrorStatus) { + case XpmSuccess: + return; + case XpmColorError: + warning = "Could not parse or alloc requested color"; + break; + case XpmOpenFailed: + error = "Cannot open file"; + break; + case XpmFileInvalid: + error = "Invalid XPM file"; + break; + case XpmNoMemory: + error = "Not enough memory"; + break; + case XpmColorFailed: + error = "Failed to parse or alloc some color"; + break; + } + + if (warning) + printf("%s Xpm Warning: %s.\n", tag, warning); + + if (error) { + printf("%s Xpm Error: %s.\n", tag, error); + Punt(1); + } +} + +void +Punt(i) + int i; +{ + if (icon.pixmap) { + XFreePixmap(dpy, icon.pixmap); + if (icon.mask) + XFreePixmap(dpy, icon.mask); + + XFreeColors(dpy, colormap, + icon.attributes.pixels, icon.attributes.npixels, 0); + + XpmFreeAttributes(&icon.attributes); + } + if (view.pixmap) { + XFreePixmap(dpy, view.pixmap); + if (view.mask) + XFreePixmap(dpy, view.mask); + + XFreeColors(dpy, colormap, + view.attributes.pixels, view.attributes.npixels, 0); + + XpmFreeAttributes(&view.attributes); + } + exit(i); +} + +void +kinput(widget, tag, xe, b) + Widget widget; + char *tag; + XEvent *xe; + Boolean *b; +{ + char c = '\0'; + + XLookupString(&(xe->xkey), &c, 1, NULL, NULL); + if (c == 'q' || c == 'Q') + Punt(0); +} diff --git a/src/xpm/sxpm.man b/src/xpm/sxpm.man new file mode 100644 index 0000000..28b6d44 --- /dev/null +++ b/src/xpm/sxpm.man @@ -0,0 +1,89 @@ +.\"Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT +.TH SXPM 1 +.PD +.ad b +.SH NAME +sxpm \- Show an XPM (X PixMap) file and/or convert XPM2 files to XPM version 3. +.SH SYNOPSIS +\fBsxpm\fR +[\|\fB-d\fR displayname\|] +[\|\fB-g\fR geometry\|] +[\|\fB-hints\fR\|] +[\|\fB-icon\fR filename\|] +[\|\fB-s\fR symbol color_name\|] +[\|\fB-p\fR symbol pixel_value\|] +[\|\fB-plaid\| | \|\fRfilename\| | \|-\|] +[\|\fB-o\fR filename\| | \|\fB-o\fR -\|] +[\|\fB-nod\fR\|] +[\|\fB-rgb\fR filename\|] +[\|\fB-c\fR\|] +[\|\fB-v\fR\|] +.SH DESCRIPTION +.PP +The \fIsxpm\fP program can be used to view any XPM (version 2 or 3) file and/or +to convert a file from XPM2 to XPM version 3. If \fIsxpm\fP is run without any +option specified, the usage is displayed. If no geometry is specified, the +show window will have the size of the read pixmap. Pressing the key Q in the +window will quit the program. +.SH OPTIONS +.TP 8 +.B \-d \fIdisplay\fP +Specifies the display to connect to. +.TP 8 +.B \-g \fIgeom\fP +Window geometry (default is pixmap's size). +.TP 8 +.B \-hints +Set ResizeInc for window. +.TP 8 +.B \-icon \fIfilename\fP +Set icon to pixmap created from the file \fIfilename\fP. +.TP 8 +.B \-s \fIsymbol colorname\fP +Overwrite default color to \fIsymbol\fP to \fIcolorname\fp. +.TP 8 +.B \-p \fIsymbol pixelvalue\fP +Overwrite default color to \fIsymbol\fP to \fIpixelvalue\fp. +.TP 8 +.B \-closecolors +Try to use "close colors" before reverting to other visuals. +.TP 8 +.B \-plaid +Show the plaid pixmap which is stored as data\fP. +.TP 8 +.B \fIfilename\fP +Read from the file \fIfilename\fP and from standard input if \fIfilename\fP is '-'. +If no input is specified sxpm reads from standard input. +.TP 8 +.B \-o \fIfilename\fP +Write to the file \fIfilename\fP (overwrite if it already exists) and to +standard output if \fIfilename\fP is '-'. +.TP 8 +.B \-nod +Do not display the pixmap in a window. (Useful when using as converter) +.TP 8 +.B \-rgb \fIfilename\fP +Search color names in the file \fIfilename\fP and write them out instead of +the rgb values. +.TP 8 +.B \-c +To use a private colormap. +.TP 8 +.B \-v +Verbose - to print out extensions (stderr). + + +.SH KNOWN BUGS +When converting a file from XPM2 to XPM version 3, if several pixels (symbols) +get the same color only one will be in the file written out. +.br +Some window managers may not accept a pixmap which is not a bitmap as icon +because this does not respect ICCCM, many of the well known ones will accept +it though. + +.SH AUTHOR +Arnaud Le Hors (lehors@sophia.inria.fr) +.br +Bull Research France +.br +Copyright (C) 1990-92,92 by Groupe Bull. diff --git a/src/xpm/xpm.h b/src/xpm/xpm.h new file mode 100644 index 0000000..e12b42c --- /dev/null +++ b/src/xpm/xpm.h @@ -0,0 +1,237 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* xpm.h: * +* * +* XPM library * +* Include file * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifndef XPM_h +#define XPM_h + +#ifdef VMS +#include "decw$include:Xlib.h" +#include "decw$include:Intrinsic.h" +#include "sys$library:stdio.h" +#else +#include <stdio.h> +#include <X11/Xlib.h> +#include <X11/Intrinsic.h> +#endif + +/* we keep the same codes as for Bitmap management */ +#ifndef _XUTIL_H_ +#ifdef VMS +#include "decw$include:Xutil.h" +#else +#include <X11/Xutil.h> +#endif +#endif + +/* Return ErrorStatus codes: + * null if full success + * positive if partial success + * negative if failure + */ + +#define XpmColorError 1 +#define XpmSuccess 0 +#define XpmOpenFailed -1 +#define XpmFileInvalid -2 +#define XpmNoMemory -3 +#define XpmColorFailed -4 + + +typedef struct { + char *name; /* Symbolic color name */ + char *value; /* Color value */ + Pixel pixel; /* Color pixel */ +} XpmColorSymbol; + +typedef struct { + char *name; /* name of the extension */ + unsigned int nlines; /* number of lines in this extension */ + char **lines; /* pointer to the extension array of + strings */ +} XpmExtension; + +typedef struct { + unsigned long valuemask; /* Specifies which attributes are + * defined */ + + Visual *visual; /* Specifies the visual to use */ + Colormap colormap; /* Specifies the colormap to use */ + unsigned int depth; /* Specifies the depth */ + unsigned int width; /* Returns the width of the created + * pixmap */ + unsigned int height; /* Returns the height of the created + * pixmap */ + unsigned int x_hotspot; /* Returns the x hotspot's + * coordinate */ + unsigned int y_hotspot; /* Returns the y hotspot's + * coordinate */ + unsigned int cpp; /* Specifies the number of char per + * pixel */ + Pixel *pixels; /* List of used color pixels */ + unsigned int npixels; /* Number of pixels */ + XpmColorSymbol *colorsymbols; /* Array of color symbols to + * override */ + unsigned int numsymbols; /* Number of symbols */ + char *rgb_fname; /* RGB text file name */ + unsigned int nextensions; /* number of extensions */ + XpmExtension *extensions; /* pointer to array of extensions */ + + /* Infos */ + unsigned int ncolors; /* Number of colors */ + char ***colorTable; /* Color table pointer */ + char *hints_cmt; /* Comment of the hints section */ + char *colors_cmt; /* Comment of the colors section */ + char *pixels_cmt; /* Comment of the pixels section */ + unsigned int mask_pixel; /* Transparent pixel's color table + * index */ + /* Color Allocation Directives */ + unsigned int exactColors; /* Only use exact colors for visual */ + unsigned int closeness; /* Allowable RGB deviation */ + +} XpmAttributes; + +/* Xpm attribute value masks bits */ +#define XpmVisual (1L<<0) +#define XpmColormap (1L<<1) +#define XpmDepth (1L<<2) +#define XpmSize (1L<<3) /* width & height */ +#define XpmHotspot (1L<<4) /* x_hotspot & y_hotspot */ +#define XpmCharsPerPixel (1L<<5) +#define XpmColorSymbols (1L<<6) +#define XpmRgbFilename (1L<<7) +#define XpmInfos (1L<<8) /* all infos members */ +#define XpmExtensions (1L<<10) + +#define XpmReturnPixels (1L<<9) +#define XpmReturnInfos XpmInfos +#define XpmReturnExtensions XpmExtensions + +#define XpmExactColors (1L<<11) +#define XpmCloseness (1L<<12) + +/* + * minimal portability layer between ansi and KR C + */ + +/* forward declaration of functions with prototypes */ + +#if __STDC__ || defined(__cplusplus) || defined(c_plusplus) + /* ANSI || C++ */ +#define FUNC(f, t, p) extern t f p +#define LFUNC(f, t, p) static t f p +#else /* K&R */ +#define FUNC(f, t, p) extern t f() +#define LFUNC(f, t, p) static t f() +#endif /* end of K&R */ + + +/* + * functions declarations + */ + +#ifdef __cplusplus +extern "C" { +#endif + + FUNC(XpmCreatePixmapFromData, int, (Display * display, + Drawable d, + char **data, + Pixmap * pixmap_return, + Pixmap * shapemask_return, + XpmAttributes * attributes)); + + FUNC(XpmCreateDataFromPixmap, int, (Display * display, + char ***data_return, + Pixmap pixmap, + Pixmap shapemask, + XpmAttributes * attributes)); + + FUNC(XpmReadFileToPixmap, int, (Display * display, + Drawable d, + char *filename, + Pixmap * pixmap_return, + Pixmap * shapemask_return, + XpmAttributes * attributes)); + + FUNC(XpmWriteFileFromPixmap, int, (Display * display, + char *filename, + Pixmap pixmap, + Pixmap shapemask, + XpmAttributes * attributes)); + + FUNC(XpmCreateImageFromData, int, (Display * display, + char **data, + XImage ** image_return, + XImage ** shapemask_return, + XpmAttributes * attributes)); + + FUNC(XpmCreateDataFromImage, int, (Display * display, + char ***data_return, + XImage * image, + XImage * shapeimage, + XpmAttributes * attributes)); + + FUNC(XpmReadFileToImage, int, (Display * display, + char *filename, + XImage ** image_return, + XImage ** shapeimage_return, + XpmAttributes * attributes)); + + FUNC(XpmWriteFileFromImage, int, (Display * display, + char *filename, + XImage * image, + XImage * shapeimage, + XpmAttributes * attributes)); + + FUNC(XpmAttributesSize, int, ()); + FUNC(XpmFreeAttributes, int, (XpmAttributes * attributes)); + FUNC(XpmFreeExtensions, int, (XpmExtension * extensions, int nextensions)); + +#ifdef __cplusplus +} /* for C++ V2.0 */ + +#endif + + +/* backward compatibility */ + +/* for version 3.0c */ +#define XpmPixmapColorError XpmColorError +#define XpmPixmapSuccess XpmSuccess +#define XpmPixmapOpenFailed XpmOpenFailed +#define XpmPixmapFileInvalid XpmFileInvalid +#define XpmPixmapNoMemory XpmNoMemory +#define XpmPixmapColorFailed XpmColorFailed + +#define XpmReadPixmapFile(dpy, d, file, pix, mask, att) \ + XpmReadFileToPixmap(dpy, d, file, pix, mask, att) +#define XpmWritePixmapFile(dpy, file, pix, mask, att) \ + XpmWriteFileFromPixmap(dpy, file, pix, mask, att) + +/* for version 3.0b */ +#define PixmapColorError XpmColorError +#define PixmapSuccess XpmSuccess +#define PixmapOpenFailed XpmOpenFailed +#define PixmapFileInvalid XpmFileInvalid +#define PixmapNoMemory XpmNoMemory +#define PixmapColorFailed XpmColorFailed + +#define ColorSymbol XpmColorSymbol + +#define XReadPixmapFile(dpy, d, file, pix, mask, att) \ + XpmReadFileToPixmap(dpy, d, file, pix, mask, att) +#define XWritePixmapFile(dpy, file, pix, mask, att) \ + XpmWriteFileFromPixmap(dpy, file, pix, mask, att) +#define XCreatePixmapFromData(dpy, d, data, pix, mask, att) \ + XpmCreatePixmapFromData(dpy, d, data, pix, mask, att) +#define XCreateDataFromPixmap(dpy, data, pix, mask, att) \ + XpmCreateDataFromPixmap(dpy, data, pix, mask, att) + +#endif diff --git a/src/xpm/xpmP.h b/src/xpm/xpmP.h new file mode 100644 index 0000000..e65a68c --- /dev/null +++ b/src/xpm/xpmP.h @@ -0,0 +1,279 @@ +/* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */ +/*****************************************************************************\ +* xpmP.h: * +* * +* XPM library * +* Private Include file * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifndef XPMP_h +#define XPMP_h + +#ifdef Debug +/* memory leak control tool */ +#include <mnemosyne.h> +#endif + +#ifdef VMS +#include "decw$include:Xlib.h" +#include "decw$include:Intrinsic.h" +#include "sys$library:stdio.h" +#else +#include <stdio.h> +#include <stdlib.h> +#include <X11/Xlib.h> +#include <X11/Intrinsic.h> +/* stdio.h doesn't declare popen on a Sequent DYNIX OS */ +#ifdef sequent +extern FILE *popen(); +#endif +#endif + +#include "xpm.h" + +/* we keep the same codes as for Bitmap management */ +#ifndef _XUTIL_H_ +#ifdef VMS +#include "decw$include:Xutil.h" +#else +#include <X11/Xutil.h> +#endif +#endif + +#if defined(SYSV) || defined(SVR4) +#define bcopy(source, dest, count) memcpy(dest, source, count) +#define bzero(addr, count) memset(addr, 0, count) +#endif + +typedef struct { + unsigned int type; + union { + FILE *file; + char **data; + } stream; + char *cptr; + unsigned int line; + int CommentLength; + char Comment[BUFSIZ]; + char *Bcmt, *Ecmt, Bos, Eos; +} xpmData; + +#define XPMARRAY 0 +#define XPMFILE 1 +#define XPMPIPE 2 + +typedef unsigned char byte; + +#define EOL '\n' +#define TAB '\t' +#define SPC ' ' + +typedef struct { + char *type; /* key word */ + char *Bcmt; /* string beginning comments */ + char *Ecmt; /* string ending comments */ + char Bos; /* character beginning strings */ + char Eos; /* character ending strings */ + char *Strs; /* strings separator */ + char *Dec; /* data declaration string */ + char *Boa; /* string beginning assignment */ + char *Eoa; /* string ending assignment */ +} xpmDataType; + +extern xpmDataType xpmDataTypes[]; + +/* + * rgb values and ascii names (from rgb text file) rgb values, + * range of 0 -> 65535 color mnemonic of rgb value + */ +typedef struct { + int r, g, b; + char *name; +} xpmRgbName; + +/* Maximum number of rgb mnemonics allowed in rgb text file. */ +#define MAX_RGBNAMES 1024 + +extern char *xpmColorKeys[]; + +#define TRANSPARENT_COLOR "None" /* this must be a string! */ + +/* number of xpmColorKeys */ +#define NKEYS 5 + +/* + * key numbers for visual type, they must fit along with the number key of + * each corresponding element in xpmColorKeys[] defined in xpm.h + */ +#define MONO 2 +#define GRAY4 3 +#define GRAY 4 +#define COLOR 5 + +/* structure containing data related to an Xpm pixmap */ +typedef struct { + char *name; + unsigned int width; + unsigned int height; + unsigned int cpp; + unsigned int ncolors; + char ***colorTable; + unsigned int *pixelindex; + XColor *xcolors; + char **colorStrings; + unsigned int mask_pixel; /* mask pixel's colorTable index */ +} xpmInternAttrib; + +#define UNDEF_PIXEL 0x80000000 + +/* XPM private routines */ + +FUNC(xpmWriteData, int, (xpmData * mdata, + xpmInternAttrib * attrib, XpmAttributes * attributes)); + +FUNC(xpmCreateData, int, (char ***data_return, + xpmInternAttrib * attrib, XpmAttributes * attributes)); + +FUNC(xpmParseDataAndCreateImage, int, (xpmData * data, + Display * display, + XImage ** image_return, + XImage ** shapeimage_return, + xpmInternAttrib * attrib_return, + XpmAttributes * attributes)); + +FUNC(xpmCreateImage, int, (Display * display, + xpmInternAttrib * attrib, + XImage ** image_return, + XImage ** shapeimage_return, + XpmAttributes * attributes)); + +FUNC(xpmParseData, int, (xpmData * data, + xpmInternAttrib * attrib_return, + XpmAttributes * attributes)); + +FUNC(xpmScanImage, int, (Display * display, + XImage * image, + XImage * shapeimage, + XpmAttributes * attributes, + xpmInternAttrib * attrib)); + +FUNC(xpmFreeColorTable, int, (char ***colorTable, int ncolors)); + +FUNC(xpmInitInternAttrib, int, (xpmInternAttrib * xmpdata)); + +FUNC(xpmFreeInternAttrib, int, (xpmInternAttrib * xmpdata)); + +FUNC(xpmSetAttributes, int, (xpmInternAttrib * attrib, + XpmAttributes * attributes)); + +FUNC(xpmGetAttributes, int, (XpmAttributes * attributes, + xpmInternAttrib * attrib)); + +/* I/O utility */ + +FUNC(xpmNextString, int, (xpmData * mdata)); +FUNC(xpmNextUI, int, (xpmData * mdata, unsigned int *ui_return)); + +#define xpmGetC(mdata) \ + (mdata->type ? (getc(mdata->stream.file)) : (*mdata->cptr++)) + +FUNC(xpmNextWord, unsigned int, (xpmData * mdata, char *buf)); +FUNC(xpmGetCmt, int, (xpmData * mdata, char **cmt)); +FUNC(xpmReadFile, int, (char *filename, xpmData * mdata)); +FUNC(xpmWriteFile, int, (char *filename, xpmData * mdata)); +FUNC(xpmOpenArray, void, (char **data, xpmData * mdata)); +FUNC(XpmDataClose, int, (xpmData * mdata)); + +/* RGB utility */ + +FUNC(xpmReadRgbNames, int, (char *rgb_fname, xpmRgbName * rgbn)); +FUNC(xpmGetRgbName, char *, (xpmRgbName * rgbn, int rgbn_max, + int red, int green, int blue)); +FUNC(xpmFreeRgbNames, void, (xpmRgbName * rgbn, int rgbn_max)); + +FUNC(xpm_xynormalizeimagebits, void, (register unsigned char *bp, + register XImage * img)); +FUNC(xpm_znormalizeimagebits, void, (register unsigned char *bp, + register XImage * img)); + +/* + * Macros + * + * The XYNORMALIZE macro determines whether XY format data requires + * normalization and calls a routine to do so if needed. The logic in + * this module is designed for LSBFirst byte and bit order, so + * normalization is done as required to present the data in this order. + * + * The ZNORMALIZE macro performs byte and nibble order normalization if + * required for Z format data. + * + * The XYINDEX macro computes the index to the starting byte (char) boundary + * for a bitmap_unit containing a pixel with coordinates x and y for image + * data in XY format. + * + * The ZINDEX* macros compute the index to the starting byte (char) boundary + * for a pixel with coordinates x and y for image data in ZPixmap format. + * + */ + +#define XYNORMALIZE(bp, img) \ + if ((img->byte_order == MSBFirst) || (img->bitmap_bit_order == MSBFirst)) \ + xpm_xynormalizeimagebits((unsigned char *)(bp), img) + +#define ZNORMALIZE(bp, img) \ + if (img->byte_order == MSBFirst) \ + xpm_znormalizeimagebits((unsigned char *)(bp), img) + +#define XYINDEX(x, y, img) \ + ((y) * img->bytes_per_line) + \ + (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3) + +#define ZINDEX(x, y, img) ((y) * img->bytes_per_line) + \ + (((x) * img->bits_per_pixel) >> 3) + +#define ZINDEX32(x, y, img) ((y) * img->bytes_per_line) + ((x) << 2) + +#define ZINDEX16(x, y, img) ((y) * img->bytes_per_line) + ((x) << 1) + +#define ZINDEX8(x, y, img) ((y) * img->bytes_per_line) + (x) + +#define ZINDEX1(x, y, img) ((y) * img->bytes_per_line) + ((x) >> 3) + +#if __STDC__ +#define Const const +#else +#define Const /**/ +#endif + +/* + * there are structures and functions related to hastable code + */ + +typedef struct _xpmHashAtom { + char *name; + void *data; +} *xpmHashAtom; + +typedef struct { + int size; + int limit; + int used; + xpmHashAtom *atomTable; +} xpmHashTable; + +FUNC(xpmHashTableInit, int, (xpmHashTable *table)); +FUNC(xpmHashTableFree, void, (xpmHashTable *table)); +FUNC(xpmHashSlot, xpmHashAtom *, (xpmHashTable *table, char *s)); +FUNC(xpmHashIntern, int, (xpmHashTable *table, char *tag, void *data)); + +#define HashAtomData(i) ((void *)i) +#define HashColorIndex(slot) ((unsigned int)(unsigned long)((*slot)->data)) +#define USE_HASHTABLE (cpp > 2 && ncolors > 4) + +#ifdef NEED_STRDUP +FUNC(strdup, char *, (char *s1)); +#endif + +#endif |