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