/**************************************************************************** * NCSA Mosaic for the X Window System * * Software Development Group * * National Center for Supercomputing Applications * * University of Illinois at Urbana-Champaign * * 605 E. Springfield, Champaign IL 61820 * * mosaic@ncsa.uiuc.edu * * * * Copyright (C) 1993, Board of Trustees of the University of Illinois * * * * NCSA Mosaic software, both binary and source (hereafter, Software) is * * copyrighted by The Board of Trustees of the University of Illinois * * (UI), and ownership remains with the UI. * * * * The UI grants you (hereafter, Licensee) a license to use the Software * * for academic, research and internal business purposes only, without a * * fee. Licensee may distribute the binary and source code (if released) * * to third parties provided that the copyright notice and this statement * * appears on all copies and that no charge is associated with such * * copies. * * * * Licensee may make derivative works. However, if Licensee distributes * * any derivative work based on or derived from the Software, then * * Licensee will (1) notify NCSA regarding its distribution of the * * derivative work, and (2) clearly notify users that such derivative * * work is a modified version and not the original NCSA Mosaic * * distributed by the UI. * * * * Any Licensee wishing to make commercial use of the Software should * * contact the UI, c/o NCSA, to negotiate an appropriate license for such * * commercial use. Commercial use includes (1) integration of all or * * part of the source code into a product for sale or license by or on * * behalf of Licensee to third parties, or (2) distribution of the binary * * code or source code to third parties that need it to utilize a * * commercial product sold or licensed by or on behalf of Licensee. * * * * UI MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR * * ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED * * WARRANTY. THE UI SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY THE * * USERS OF THIS SOFTWARE. * * * * By using or copying this Software, Licensee agrees to abide by the * * copyright law and all other applicable laws of the U.S. including, but * * not limited to, export control laws, and the terms of this license. * * UI shall have the right to terminate this license immediately by * * written notice upon Licensee's breach of, or non-compliance with, any * * of its terms. Licensee may be held legally responsible for any * * copyright infringement that is caused or encouraged by Licensee's * * failure to abide by the terms of this license. * * * * Comments and questions are welcome and can be sent to * * mosaic-x@ncsa.uiuc.edu. * ****************************************************************************/ #include "../config.h" /* * The following XPM reading code was based on the libXpm code, which I * am free to use as long as I include the following copyright: */ /* * Copyright 1990-93 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. * */ #include struct timeval Tv; struct timezone Tz; #include "mosaic.h" #include "xpmread.h" #include #include "xpm.h" /*for memset*/ #include extern Display *dsp; extern int installed_colormap; extern Colormap installed_cmap; #ifndef DISABLE_TRACE extern int srcTrace; #endif 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 */ }; 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 }; /* * Free the computed color table */ void 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) XpmFree(*cts); XpmFree(*ct); } XpmFree(colorTable); } } /* * Intialize the xpmInternAttrib pointers to Null to know * which ones must be freed later on. */ void 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 */ void xpmFreeInternAttrib(attrib) xpmInternAttrib *attrib; { unsigned int a, ncolors; char **sptr; if (attrib->colorTable) xpmFreeColorTable_(attrib->colorTable, attrib->ncolors); if (attrib->pixelindex) XpmFree(attrib->pixelindex); if (attrib->xcolors) XpmFree(attrib->xcolors); if (attrib->colorStrings) { ncolors = attrib->ncolors; for (a = 0, sptr = attrib->colorStrings; a < ncolors; a++, sptr++) if (*sptr) XpmFree(*sptr); XpmFree(attrib->colorStrings); } } /* * open the given file to be read as an xpmData which is returned. */ int xpmReadFile(filename, mdata) char *filename; xpmData *mdata; { #ifdef ZPIPE char *compressfile, buf[BUFSIZ]; struct stat status; #endif if (!filename) { mdata->stream.file = (stdin); mdata->type = XPMFILE; } else { #ifdef ZPIPE if ((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 ((strlen(filename) > 2) && !strcmp(".z", filename + (strlen(filename) - 2))) { mdata->type = XPMPIPE; sprintf(buf, "gunzip -c %s", filename); if (!(mdata->stream.file = popen(buf, "r"))) return (XpmOpenFailed); } else { if (!(compressfile = (char *) XpmMalloc(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"))) { XpmFree(compressfile); return (XpmOpenFailed); } mdata->type = XPMPIPE; } else { strcpy(compressfile, filename); strcat(compressfile, ".z"); if (!stat(compressfile, &status)) { sprintf(buf, "gunzip -c %s", compressfile); if (!(mdata->stream.file = popen(buf, "r"))) { XpmFree(compressfile); return (XpmOpenFailed); } mdata->type = XPMPIPE; } else { #endif if (!(mdata->stream.file = fopen(filename, "r"))) { #ifdef ZPIPE XpmFree(compressfile); #endif return (XpmOpenFailed); } mdata->type = XPMFILE; #ifdef ZPIPE } } XpmFree(compressfile); } #endif } mdata->CommentLength = 0; return (XpmSuccess); } /* * close the file related to the xpmData if any */ int xpmDataClose(mdata) xpmData *mdata; { switch (mdata->type) { case XPMARRAY: case XPMBUFFER: 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 } return 0; } static int ParseComment(mdata) xpmData *mdata; { if (mdata->type == XPMBUFFER) { register char c; register unsigned int n = 0; unsigned int notend; char *s, *s2; s = mdata->Comment; *s = mdata->Bcmt[0]; /* skip the string beginning comment */ s2 = mdata->Bcmt; do { c = *mdata->cptr++; *++s = c; n++; s2++; } while (c == *s2 && *s2 != '\0' && c && c != mdata->Bos); if (*s2 != '\0') { /* this wasn't the beginning of a comment */ mdata->cptr -= n; return 0; } /* store comment */ mdata->Comment[0] = *s; s = mdata->Comment; notend = 1; n = 0; while (notend) { s2 = mdata->Ecmt; while (*s != *s2 && c && c != mdata->Bos) { c = *mdata->cptr++; *++s = c; n++; } mdata->CommentLength = n; do { c = *mdata->cptr++; n++; *++s = c; s2++; } while (c == *s2 && *s2 != '\0' && c && c != mdata->Bos); if (*s2 == '\0') { /* this is the end of the comment */ notend = 0; mdata->cptr--; } } return 0; } else { 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); } } return 0; } } /* * skip to the end of the current string and the beginning of the next one */ int xpmNextString(mdata) xpmData *mdata; { if (!mdata->type) mdata->cptr = (mdata->stream.data)[++mdata->line]; else if (mdata->type == XPMBUFFER) { register char c; /* get to the end of the current string */ if (mdata->Eos) while ((c = *mdata->cptr++) && c != mdata->Eos); /* * then get to the beginning of the next string looking for possible * comment */ if (mdata->Bos) { while ((c = *mdata->cptr++) && c != mdata->Bos) if (mdata->Bcmt && c == mdata->Bcmt[0]) ParseComment(mdata); } else if (mdata->Bcmt) { /* XPM2 natural */ while ((c = *mdata->cptr++) == mdata->Bcmt[0]) ParseComment(mdata); mdata->cptr--; } } 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 if (mdata->Bcmt) { /* XPM2 natural */ while ((c = getc(file)) == mdata->Bcmt[0]) ParseComment(mdata); ungetc(c, file); } } return 0; } 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 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 ***) XpmCalloc(ncolors, sizeof(char **)); if (!colorTable) return (XpmNoMemory); for (a = 0, ct = colorTable; a < ncolors; a++, ct++) { xpmNextString(data); /* skip the line */ cts = *ct = (char **) XpmCalloc((NKEYS + 1), sizeof(char *)); if (!cts) { xpmFreeColorTable_(colorTable, ncolors); return (XpmNoMemory); } /* * read pixel value */ *cts = (char *) XpmMalloc(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(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 *) XpmMalloc(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 *) XpmMalloc(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 *) XpmMalloc(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));*/ memset(colidx, 0, 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 { XpmFree(iptr2); return (XpmFileInvalid); } } } } break; case (2): /* Optimize for double character * colors */ { unsigned short cidx[256][256]; /* bzero(cidx, 256 * 256 * sizeof(short));*/ memset(cidx, 0, 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 { XpmFree(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 */ XpmFree(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 */ XpmFree(iptr2); return (XpmFileInvalid); } *iptr = a; } } } } break; } *pixels = iptr2; return (XpmSuccess); } /* * 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) return 0; if (!mdata->type || mdata->type == XPMBUFFER) { while (isspace(c = *mdata->cptr) && c != mdata->Eos) mdata->cptr++; do { c = *mdata->cptr++; *buf++ = c; n++; } while (!isspace(c) && c != mdata->Eos && (n < BUFSIZ)); n--; mdata->cptr--; } else { FILE *file = mdata->stream.file; while ((c = getc(file)) != EOF && isspace(c) && c != mdata->Eos); while (!isspace(c) && c != mdata->Eos && c != EOF && (n < BUFSIZ)) { *buf++ = c; n++; c = getc(file); } ungetc(c, file); } return (n); } /* * 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); } /* * parse xpm header */ int xpmParseHeader(mdata) xpmData *mdata; { char buf[BUFSIZ]; int l, n = 0; if (mdata->type) { 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; } else return XpmFileInvalid; } else return XpmFileInvalid; } return XpmSuccess; } /* * get the current comment line */ int xpmGetCmt(mdata, cmt) xpmData *mdata; char **cmt; { if (!mdata->type) *cmt = NULL; else if (mdata->CommentLength) { *cmt = (char *) XpmMalloc(mdata->CommentLength + 1); strncpy(*cmt, mdata->Comment, mdata->CommentLength); (*cmt)[mdata->CommentLength] = '\0'; mdata->CommentLength = 0; } else *cmt = NULL; return 0; } #undef RETURN #define RETURN(status) \ { if (colorTable) xpmFreeColorTable_(colorTable, ncolors); \ if (pixelindex) XpmFree(pixelindex); \ if (hints_cmt) XpmFree(hints_cmt); \ if (colors_cmt) XpmFree(colors_cmt); \ if (pixels_cmt) XpmFree(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; /* * parse the header */ ErrorStatus = xpmParseHeader(data); if (ErrorStatus != XpmSuccess) return (ErrorStatus); /* * 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); /* * 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); } /* * 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'; } unsigned char *ReadXpm3Pixmap(FILE *fp, char *datafile, int *w, int *h, XColor *colrs, int *bg) { xpmData mdata; XpmAttributes attributes; xpmInternAttrib attrib; int ErrorStatus; int Colors; XColor tmpcolr; int i/*, j*/; char **colorStrings; char *colorName; unsigned char *pix_data; unsigned char *bptr; unsigned int *pixels; extern Widget view; #ifndef DISABLE_TRACE if (srcTrace) { gettimeofday(&Tv, &Tz); fprintf(stderr, "ReadXpm3Pixmap enter (%d.%d)\n", Tv.tv_sec, Tv.tv_usec); } #endif *w = 0; *h = 0; attributes.valuemask = XpmReturnPixels; if ((ErrorStatus = xpmReadFile(datafile, &mdata)) != XpmSuccess) { return(NULL); } xpmInitInternAttrib(&attrib); ErrorStatus = xpmParseData(&mdata, &attrib, &attributes); if (ErrorStatus != XpmSuccess) { xpmFreeInternAttrib(&attrib); xpmDataClose(&mdata); return(NULL); } *w = (int)attrib.width; *h = (int)attrib.height; Colors = (int)attrib.ncolors; for (i=0; i (256 - 1)) pix = 0; *bptr++ = (unsigned char)pix; pixels++; } xpmFreeInternAttrib(&attrib); xpmDataClose(&mdata); #ifndef DISABLE_TRACE if (srcTrace) { gettimeofday(&Tv, &Tz); fprintf(stderr, "ReadXpm3Pixmap exit (%d.%d)\n", Tv.tv_sec, Tv.tv_usec); } #endif return(pix_data); } unsigned char *ProcessXpm3Data(Widget wid, char **xpmdata, int *w, int *h, XColor *colrs, int *bg) { xpmData mdata; XpmAttributes attributes; xpmInternAttrib attrib; int ErrorStatus; int Colors; XColor tmpcolr; int i/*, j*/; char **colorStrings; char *colorName; unsigned char *pix_data; unsigned char *bptr; unsigned int *pixels; extern Widget view; *w = 0; *h = 0; attributes.valuemask = XpmReturnPixels; xpmOpenArray(xpmdata, &mdata); xpmInitInternAttrib(&attrib); ErrorStatus = xpmParseData(&mdata, &attrib, &attributes); if (ErrorStatus != XpmSuccess) { xpmFreeInternAttrib(&attrib); xpmDataClose(&mdata); return(NULL); } *w = (int)attrib.width; *h = (int)attrib.height; Colors = (int)attrib.ncolors; for (i=0; i (256 - 1)) pix = 0; *bptr++ = (unsigned char)pix; pixels++; } xpmFreeInternAttrib(&attrib); xpmDataClose(&mdata); #ifndef DISABLE_TRACE if (srcTrace) { gettimeofday(&Tv, &Tz); fprintf(stderr, "ReadXpm3Pixmap exit (%d.%d)\n", Tv.tv_sec, Tv.tv_usec); } #endif return(pix_data); }