Back to index

plt-scheme  4.2.1
Defines | Functions | Variables
parse.c File Reference
#include "xpmP.h"
#include <ctype.h>
#include <strings.h>

Go to the source code of this file.

Defines

#define RETURN(status)
#define FREE_CIDX

Functions

 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, XpmColor **colorTablePtr, xpmHashTable *hashtable))
 LFUNC (ParsePixels, int,(xpmData *data, unsigned int width, unsigned int height, unsigned int ncolors, unsigned int cpp, XpmColor *colorTable, xpmHashTable *hashtable, unsigned int **pixels))
 LFUNC (ParseExtensions, int,(xpmData *data, XpmExtension **extensions, unsigned int *nextensions))
int xpmParseData (xpmData *data, XpmImage *image, XpmInfo *info)
static int ParseValues (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)
static int ParseColors (xpmData *data, unsigned int ncolors, unsigned int cpp, XpmColor **colorTablePtr, xpmHashTable *hashtable)
static int ParsePixels (xpmData *data, unsigned int width, unsigned int height, unsigned int ncolors, unsigned int cpp, XpmColor *colorTable, xpmHashTable *hashtable, unsigned int **pixels)
static int ParseExtensions (xpmData *data, XpmExtension **extensions, unsigned int *nextensions)

Variables

char * xpmColorKeys []

Define Documentation

#define FREE_CIDX
Value:
{int f; for (f = 0; f < 256; f++) \
if (cidx[f]) XpmFree(cidx[f]);}
#define RETURN (   status)
Value:
{ \
    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); \
}

Definition at line 77 of file parse.c.


Function Documentation

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, XpmColor **colorTablePtr, xpmHashTable *hashtable  
)
LFUNC ( ParsePixels  ,
int  ,
(xpmData *data, unsigned int width, unsigned int height, unsigned int ncolors, unsigned int cpp, XpmColor *colorTable, xpmHashTable *hashtable, unsigned int **pixels)   
)
LFUNC ( ParseExtensions  ,
int  ,
(xpmData *data, XpmExtension **extensions, unsigned int *nextensions)   
)
static int ParseColors ( xpmData data,
unsigned int  ncolors,
unsigned int  cpp,
XpmColor **  colorTablePtr,
xpmHashTable hashtable 
) [static]

Definition at line 329 of file parse.c.

{
    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 **sptr, *s;
    XpmColor *color;
    XpmColor *colorTable;
    char **defaults;
    int ErrorStatus;

    colorTable = (XpmColor *) XpmCalloc(ncolors, sizeof(XpmColor));
    if (!colorTable)
       return (XpmNoMemory);

    if (!data->format) {           /* XPM 2 or 3 */
       for (a = 0, color = colorTable; a < ncolors; a++, color++) {
           xpmNextString(data);    /* skip the line */

           /*
            * read pixel value
            */
           color->string = (char *) XpmMalloc(cpp + 1);
           if (!color->string) {
              xpmFreeColorTable(colorTable, ncolors);
              return (XpmNoMemory);
           }
           for (b = 0, s = color->string; 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, color->string, HashAtomData(a));
              if (ErrorStatus != XpmSuccess) {
                  xpmFreeColorTable(colorTable, ncolors);
                  return (ErrorStatus);
              }
           }

           /*
            * read color keys and values
            */
           defaults = (char **) color;
           curkey = 0;
           lastwaskey = 0;
           *curbuf = '\0';         /* init curbuf */
           while (l = xpmNextWord(data, buf, BUFSIZ)) {
              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 = (char *) XpmMalloc(strlen(curbuf) + 1);
                     if (!s) {
                         xpmFreeColorTable(colorTable, ncolors);
                         return (XpmNoMemory);
                     }
                     defaults[curkey] = s;
                     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 = defaults[curkey] = (char *) XpmMalloc(strlen(curbuf) + 1);
           if (!s) {
              xpmFreeColorTable(colorTable, ncolors);
              return (XpmNoMemory);
           }
           strcpy(s, curbuf);
       }
    } else {                       /* XPM 1 */
       /* get to the beginning of the first string */
       data->Bos = '"';
       data->Eos = '\0';
       xpmNextString(data);
       data->Eos = '"';
       for (a = 0, color = colorTable; a < ncolors; a++, color++) {

           /*
            * read pixel value
            */
           color->string = (char *) XpmMalloc(cpp + 1);
           if (!color->string) {
              xpmFreeColorTable(colorTable, ncolors);
              return (XpmNoMemory);
           }
           for (b = 0, s = color->string; 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, color->string, HashAtomData(a));
              if (ErrorStatus != XpmSuccess) {
                  xpmFreeColorTable(colorTable, ncolors);
                  return (ErrorStatus);
              }
           }

           /*
            * read color values
            */
           xpmNextString(data);    /* get to the next string */
           *curbuf = '\0';         /* init curbuf */
           while (l = xpmNextWord(data, buf, BUFSIZ)) {
              if (*curbuf != '\0')
                  strcat(curbuf, " ");/* append space */
              buf[l] = '\0';
              strcat(curbuf, buf); /* append buf */
           }
           s = (char *) XpmMalloc(strlen(curbuf) + 1);
           if (!s) {
              xpmFreeColorTable(colorTable, ncolors);
              return (XpmNoMemory);
           }
           strcpy(s, curbuf);
           color->c_color = s;
           *curbuf = '\0';         /* reset curbuf */
           if (a < ncolors - 1)
              xpmNextString(data); /* get to the next string */
       }
    }
    *colorTablePtr = colorTable;
    return (XpmSuccess);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ParseExtensions ( xpmData data,
XpmExtension **  extensions,
unsigned int nextensions 
) [static]

Definition at line 644 of file parse.c.

{
    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 *) XpmMalloc(sizeof(XpmExtension));
    /* get the whole string */
    status = xpmGetString(data, &string, &l);
    if (status != XpmSuccess) {
       XpmFree(exts);
       return (status);
    }
    /* look for the key word XPMEXT, skip lines before this */
    while ((notstart = strncmp("XPMEXT", string, 6))
          && (notend = strncmp("XPMENDEXT", string, 9))) {
       XpmFree(string);
       xpmNextString(data);
       status = xpmGetString(data, &string, &l);
       if (status != XpmSuccess) {
           XpmFree(exts);
           return (status);
       }
    }
    if (!notstart)
       notend = strncmp("XPMENDEXT", string, 9);
    while (!notstart && notend) {
       /* there starts an extension */
       ext = (XpmExtension *)
           XpmRealloc(exts, (num + 1) * sizeof(XpmExtension));
       if (!ext) {
           XpmFree(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 *) XpmMalloc(l - a - 6);
       if (!ext->name) {
           XpmFree(string);
           ext->lines = NULL;
           ext->nlines = 0;
           XpmFreeExtensions(exts, num + 1);
           return (XpmNoMemory);
       }
       strncpy(ext->name, s + a, l - a - 6);
       XpmFree(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 **) XpmMalloc(sizeof(char *));
       nlines = 0;
       while ((notstart = strncmp("XPMEXT", string, 6))
              && (notend = strncmp("XPMENDEXT", string, 9))) {
           sp = (char **)
              XpmRealloc(ext->lines, (nlines + 1) * sizeof(char *));
           if (!sp) {
              XpmFree(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) {
           XpmFree(ext->lines);
           ext->lines = NULL;
       }
       ext->nlines = nlines;
       num++;
    }
    if (!num) {
       XpmFree(string);
       XpmFree(exts);
       exts = NULL;
    } else if (!notend)
       XpmFree(string);
    *nextensions = num;
    *extensions = exts;
    return (XpmSuccess);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ParsePixels ( xpmData data,
unsigned int  width,
unsigned int  height,
unsigned int  ncolors,
unsigned int  cpp,
XpmColor colorTable,
xpmHashTable hashtable,
unsigned int **  pixels 
) [static]

Definition at line 489 of file parse.c.

{
    unsigned int *iptr, *iptr2;
    unsigned int a, x, y;

#ifndef FOR_MSW
    iptr2 = (unsigned int *) XpmMalloc(sizeof(unsigned int) * width * height);
#else

    /*
     * special treatment to trick DOS malloc(size_t) where size_t is 16 bit!!
     * XpmMalloc is defined to longMalloc(long) and checks the 16 bit boundary
     */
    iptr2 = (unsigned int *)
       XpmMalloc((long) sizeof(unsigned int) * (long) width * (long) height);
#endif
    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[(unsigned char)colorTable[a].string[0]] = a + 1;

           for (y = 0; y < height; y++) {
              xpmNextString(data);
              for (x = 0; x < width; x++, iptr++) {
                  int c = xpmGetC(data);

                  if (c > 0 && c < 256 && colidx[c] != 0)
                     *iptr = colidx[c] - 1;
                  else {
                     XpmFree(iptr2);
                     return (XpmFileInvalid);
                  }
              }
           }
       }
       break;

    case (2):                      /* Optimize for double character
                                    * colors */
       {

/* free all allocated pointers at all exits */
#define FREE_CIDX {int f; for (f = 0; f < 256; f++) \
if (cidx[f]) XpmFree(cidx[f]);}

           /* array of pointers malloced by need */
           unsigned short *cidx[256];
           int char1;

           bzero(cidx, 256 * sizeof(unsigned short *)); /* init */
           for (a = 0; a < ncolors; a++) {
              char1 = colorTable[a].string[0];
              if (cidx[char1] == NULL) { /* get new memory */
                  cidx[char1] = (unsigned short *)
                     XpmCalloc(256, sizeof(unsigned short));
                  if (cidx[char1] == NULL) { /* new block failed */
                     FREE_CIDX;
                     XpmFree(iptr2);
                     return (XpmNoMemory);
                  }
              }
              cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1;
           }

           for (y = 0; y < height; y++) {
              xpmNextString(data);
              for (x = 0; x < width; x++, iptr++) {
                  int cc1 = xpmGetC(data);
                  if (cc1 > 0 && cc1 < 256) {
                     int cc2 = xpmGetC(data);
                     if (cc2 > 0 && cc2 < 256 && cidx[cc1][cc2] != 0)
                         *iptr = cidx[cc1][cc2] - 1;
                     else {
                         FREE_CIDX;
                         XpmFree(iptr2);
                         return (XpmFileInvalid);
                     }
                  } else {
                     FREE_CIDX;
                     XpmFree(iptr2);
                     return (XpmFileInvalid);
                  }
              }
           }
           FREE_CIDX;
       }
       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].string, buf))
                            break;
                     if (a == ncolors) {  /* no color matches */
                         XpmFree(iptr2);
                         return (XpmFileInvalid);
                     }
                     *iptr = a;
                  }
              }
           }
       }
       break;
    }
    *pixels = iptr2;
    return (XpmSuccess);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ParseValues ( 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 
) [static]

Definition at line 219 of file parse.c.

{
    unsigned int l;
    char buf[BUFSIZ];

    if (!data->format) {           /* XPM 2 or 3 */

       /*
        * 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, BUFSIZ);
       if (l) {
           *extensions = (l == 6 && !strncmp("XPMEXT", buf, 6));
           if (*extensions)
              *hotspot = (xpmNextUI(data, x_hotspot)
                         && xpmNextUI(data, y_hotspot));
           else {
              *hotspot = (xpmatoui(buf, l, x_hotspot)
                         && xpmNextUI(data, y_hotspot));
              l = xpmNextWord(data, buf, BUFSIZ);
              *extensions = (l == 6 && !strncmp("XPMEXT", buf, 6));
           }
       }
    } else {

       /*
        * XPM 1 file read values: width, height, ncolors, chars_per_pixel
        */
       int i;
       char *ptr;
       Bool got_one, saw_width = False, saw_height = False;
       Bool saw_ncolors = False, saw_chars_per_pixel = False;

       for (i = 0; i < 4; i++) {
           l = xpmNextWord(data, buf, BUFSIZ);
           if (l != 7 || strncmp("#define", buf, 7))
              return (XpmFileInvalid);
           l = xpmNextWord(data, buf, BUFSIZ);
           if (!l)
              return (XpmFileInvalid);
           buf[l] = '\0';
           ptr = buf;
           got_one = False;
           while (!got_one) {
              ptr = index(ptr, '_');
              if (!ptr)
                  return (XpmFileInvalid);
              switch (l - (ptr - buf)) {
              case 6:
                  if (saw_width || strncmp("_width", ptr, 6)
                     || !xpmNextUI(data, width))
                     return (XpmFileInvalid);
                  else
                     saw_width = True;
                  got_one = True;
                  break;
              case 7:
                  if (saw_height || strncmp("_height", ptr, 7)
                     || !xpmNextUI(data, height))
                     return (XpmFileInvalid);
                  else
                     saw_height = True;
                  got_one = True;
                  break;
              case 8:
                  if (saw_ncolors || strncmp("_ncolors", ptr, 8)
                     || !xpmNextUI(data, ncolors))
                     return (XpmFileInvalid);
                  else
                     saw_ncolors = True;
                  got_one = True;
                  break;
              case 16:
                  if (saw_chars_per_pixel
                     || strncmp("_chars_per_pixel", ptr, 16)
                     || !xpmNextUI(data, cpp))
                     return (XpmFileInvalid);
                  else
                     saw_chars_per_pixel = True;
                  got_one = True;
                  break;
              default:
                  ptr++;
              }
           }
           /* skip the end of line */
           xpmNextString(data);
       }
       if (!saw_width || !saw_height || !saw_ncolors || !saw_chars_per_pixel)
         return (XpmFileInvalid);

       *hotspot = 0;
       *extensions = 0;
    }
    return (XpmSuccess);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int xpmParseData ( xpmData data,
XpmImage image,
XpmInfo info 
)

Definition at line 92 of file parse.c.

{
    /* variables to return */
    unsigned int width, height, ncolors, cpp;
    unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0;
    XpmColor *colorTable = NULL;
    unsigned int *pixelindex = NULL;
    char *hints_cmt = NULL;
    char *colors_cmt = NULL;
    char *pixels_cmt = NULL;

    unsigned int cmts;
    int ErrorStatus;
    xpmHashTable hashtable;

    cmts = info && (info->valuemask & XpmReturnComments);

    /*
     * 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 (cmts)
       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) {
       if (USE_HASHTABLE)
           xpmHashTableFree(&hashtable);
       RETURN(ErrorStatus);
    }

    /*
     * store the colors comment line
     */
    if (cmts)
       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 (cmts)
       xpmGetCmt(data, &pixels_cmt);

    /*
     * parse extensions
     */
    if (info && (info->valuemask & XpmReturnExtensions))
       if (extensions) {
           ErrorStatus = ParseExtensions(data, &info->extensions,
                                     &info->nextensions);
           if (ErrorStatus != XpmSuccess)
              RETURN(ErrorStatus);
       } else {
           info->extensions = NULL;
           info->nextensions = 0;
       }

    /*
     * store found informations in the XpmImage structure
     */
    image->width = width;
    image->height = height;
    image->cpp = cpp;
    image->ncolors = ncolors;
    image->colorTable = colorTable;
    image->data = pixelindex;

    if (info) {
       if (cmts) {
           info->hints_cmt = hints_cmt;
           info->colors_cmt = colors_cmt;
           info->pixels_cmt = pixels_cmt;
       }
       if (hotspot) {
           info->x_hotspot = x_hotspot;
           info->y_hotspot = y_hotspot;
           info->valuemask |= XpmHotspot;
       }
    }
    return (XpmSuccess);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

char* xpmColorKeys[]
Initial value:
 {
    "s",                           
    "m",                           
    "g4",                          
    "g",                           
    "c",                           
}

Definition at line 66 of file parse.c.