home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume5 / xldimage / patch2 / xpixmap.c < prev   
Encoding:
C/C++ Source or Header  |  1989-11-21  |  5.6 KB  |  238 lines

  1. /* xpixmap.c:
  2.  *
  3.  * XPixMap format file read and identify routines.  these can handle any
  4.  * "format 1" XPixmap file with up to BUFSIZ - 1 chars per pixel.  it's
  5.  * not nearly as picky as it might be.
  6.  *
  7.  * unlike most image loading routines, this is X specific since it
  8.  * requires X color name parsing.  to handle this we have global X
  9.  * variables for display and screen.  it's ugly but it keeps the rest
  10.  * of the image routines clean.
  11.  *
  12.  * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
  13.  * copyright information.
  14.  */
  15.  
  16. #include "copyright.h"
  17. #include "xloadimage.h"
  18.  
  19. char *rindex();
  20.  
  21. extern Display *Disp; /* X display, null if in "identify" mode */
  22. extern int      Scrn; /* X screen number */
  23.  
  24. #define XPM_FORMAT 1
  25.  
  26. static void corrupted(fullname, zf)
  27.      char  *fullname;
  28.      ZFILE *zf;
  29. {
  30.   zclose(zf);
  31.   printf("%s: X Pixmap file is corrupted\n", fullname);
  32.   exit(1);
  33. }
  34.  
  35. Image *xpixmapLoad(fullname, name, verbose)
  36.      char         *fullname, *name;
  37.      unsigned int  verbose;
  38. { ZFILE         *zf;
  39.   char           buf[BUFSIZ];
  40.   char           what[BUFSIZ];
  41.   char          *p;
  42.   unsigned int   value;
  43.   unsigned int   format;  /* image format */
  44.   unsigned int   w, h;    /* image dimensions */
  45.   unsigned int   cpp;     /* chars per pixel */
  46.   unsigned int   ncolors; /* number of colors */
  47.   unsigned int   depth;   /* depth of image */
  48.   char         **ctable;  /* color table */
  49.   Image         *image;
  50.   XColor         xcolor;
  51.   unsigned int   a, b, x, y;
  52.   int            c;
  53.   byte          *dptr;
  54.  
  55.   if (! (zf= zopen(fullname)))
  56.     return(NULL);
  57.  
  58.   /* read #defines until we have all that are necessary or until we
  59.    * get an error
  60.    */
  61.  
  62.   format= w= h= ncolors= 0;
  63.   for (;;) {
  64.     if (! zgets(buf, BUFSIZ - 1, zf)) {
  65.       zclose(zf);
  66.       return(NULL);
  67.     }
  68.     if (!strncmp(buf, "#define", 7)) {
  69.       if (sscanf(buf, "#define %s %d", what, &value) != 2) {
  70.     zclose(zf);
  71.     return(NULL);
  72.       }
  73.       if (! (p= rindex(what, '_')))
  74.     p= what;
  75.       else
  76.     p++;
  77.       if (!strcmp(p, "format"))
  78.     format= value;
  79.       else if (!strcmp(p, "width"))
  80.     w= value;
  81.       else if (!strcmp(p, "height"))
  82.     h= value;
  83.       else if (!strcmp(p, "ncolors"))
  84.     ncolors= value;
  85.  
  86.       /* this one is ugly
  87.        */
  88.  
  89.       else if (!strcmp(p, "pixel")) { /* this isn't pretty but it works */
  90.     if (p == what)
  91.       continue;
  92.     *(--p)= '\0';
  93.     if (!(p= rindex(what, '_')) || (p == what) || strcmp(++p, "per"))
  94.       continue;
  95.     *(--p)= '\0';
  96.     if (!(p= rindex(what, '_')))
  97.       p= what;
  98.     if (strcmp(++p, "chars"))
  99.       continue;
  100.     cpp= value;
  101.       }
  102.     }
  103.     else if ((sscanf(buf, "static char * %s", what) == 1) &&
  104.          (p= rindex(what, '_')) && !strcmp(++p, "colors[]"))
  105.       break;
  106.   }
  107.  
  108.   if ((format != XPM_FORMAT) || !w || !h || !ncolors || !cpp) {
  109.     zclose(zf);
  110.     return(NULL);
  111.   }
  112.  
  113.   if (p= rindex(what, '_')) {     /* get the name in the image if there is */
  114.     *p= '\0';                     /* one */
  115.     image->title= dupString(what);
  116.   }
  117.   else {
  118.     p= what;
  119.     image->title= dupString(name);
  120.   }
  121.  
  122.   if (verbose)
  123.     printf("%s is a %dx%d X Pixmap image with %d colors titled '%s'\n",
  124.        name, w, h, ncolors, image->title);
  125.  
  126.   for (depth= 1, value= 2; value < ncolors; value <<= 1, depth++)
  127.     ;
  128.   image= newRGBImage(w, h, depth);
  129.   image->rgb.used= ncolors;
  130.  
  131.   /* read the colors array and build the image colormap
  132.    */
  133.  
  134.   ctable= (char **)lmalloc(sizeof(char *) * ncolors);
  135.   xcolor.flags= DoRed | DoGreen | DoBlue;
  136.   for (a= 0; a < ncolors; a++) {
  137.  
  138.     /* read pixel value
  139.      */
  140.  
  141.     *(ctable + a)= (char *)lmalloc(cpp);
  142.     while (((c= zgetc(zf)) != EOF) && (c != '"'))
  143.       ;
  144.     if (c == EOF)
  145.       corrupted(fullname, zf);
  146.     for (b= 0; b < cpp; b++) {
  147.       if ((c= zgetc(zf)) == '\\')
  148.     c= zgetc(zf);
  149.      if (c == EOF)
  150.     corrupted(fullname, zf);
  151.       *(*(ctable + a) + b)= (char)c;
  152.     }
  153.     if (((c= zgetc(zf)) == EOF) || (c != '"'))
  154.       corrupted(fullname, zf);
  155.  
  156.     /* read color definition and parse it
  157.      */
  158.  
  159.     while (((c= zgetc(zf)) != EOF) && (c != '"'))
  160.       ;
  161.     if (c == EOF)
  162.       corrupted(fullname, zf);
  163.     for (b= 0; ((c= zgetc(zf)) != EOF) && (c != '"'); b++) {
  164.       if (c == '\\')
  165.     c= zgetc(zf);
  166.       if (c == EOF)
  167.     corrupted(fullname, zf);
  168.       buf[b]= (char)c;
  169.     }
  170.     buf[b]= '\0';
  171.  
  172.     if (Disp) {
  173.       if (! XParseColor(Disp, DefaultColormap(Disp, Scrn), buf, &xcolor)) {
  174.     printf("%s: %s: Bad color name\n", fullname, buf);
  175.     exit(1);
  176.       }
  177.       *(image->rgb.red + a)= xcolor.red;
  178.       *(image->rgb.green + a)= xcolor.green;
  179.       *(image->rgb.blue + a)= xcolor.blue;
  180.     }
  181.   }
  182.  
  183.   for (;;) {
  184.     if (! zgets(buf, BUFSIZ - 1, zf))
  185.       corrupted(fullname, zf);
  186.     if (sscanf(buf, "static char * %s", what) == 1)
  187.       break;
  188.   }
  189.  
  190.   if (p= rindex(what, '_'))
  191.     p++;
  192.   else
  193.     p= what;
  194.   if (strcmp(p, "pixels[]"))
  195.     corrupted(fullname, zf);
  196.  
  197.   /* read in image data
  198.    */
  199.  
  200.   dptr= image->data;
  201.   for (y= 0; y < h; y++) {
  202.     while (((c= zgetc(zf)) != EOF) && (c != '"'))
  203.       ;
  204.     for (x= 0; x < w; x++) {
  205.       for (a= 0; a < cpp; a++) {
  206.     if ((c= zgetc(zf)) == '\\')
  207.       c= zgetc(zf);
  208.     if (c == EOF)
  209.       corrupted(fullname, zf);
  210.     buf[a]= (char)c;
  211.       }
  212.       for (a= 0; a < ncolors; a++)
  213.     if (!strncmp(*(ctable + a), buf, cpp))
  214.       break;
  215.       if (a == ncolors) { /* major uncool */
  216.     zclose(zf);
  217.     printf("%s: Pixel data doesn't match color data\n", fullname);
  218.     exit(1);
  219.       }
  220.       valToMem((unsigned long)a, dptr, image->pixlen);
  221.       dptr += image->pixlen;
  222.     }
  223.     if ((c= zgetc(zf)) != '"')
  224.       corrupted(fullname, zf);
  225.   }
  226.   return(image);
  227. }
  228.  
  229. int xpixmapIdent(fullname, name)
  230. { Image *image;
  231.  
  232.   if (image= xpixmapLoad(fullname, name, 1)) {
  233.     freeImage(image);
  234.     return(1);
  235.   }
  236.   return(0);
  237. }
  238.