home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume5 / xldimage / part02 / xbitmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-11-13  |  5.2 KB  |  250 lines

  1. /* xbitmap.c:
  2.  *
  3.  * at one time this was XRdBitF.c.  it bears very little resemblence to it
  4.  * now.  that was ugly code.  this is cleaner, faster, and more reliable
  5.  * in most cases.
  6.  *
  7.  * jim frost 10.06.89
  8.  *
  9.  * Copyright, 1987, Massachusetts Institute of Technology
  10.  *
  11.  * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
  12.  * copyright information.
  13.  */
  14.  
  15. #include "mit.cpyrght"
  16. #include "copyright.h"
  17. #include "xloadimage.h"
  18. #include <ctype.h>
  19.  
  20. char *rindex();
  21.  
  22. #define MAX_SIZE 255
  23.  
  24. static short        HexTable[256];  /* conversion value */
  25. static unsigned int Initialized= 0; /* easier to fill in at run time */
  26.  
  27. #define b0000 0 /* things make more sense if you see them by bit */
  28. #define b0001 1
  29. #define b0010 2
  30. #define b0011 3
  31. #define b0100 4
  32. #define b0101 5
  33. #define b0110 6
  34. #define b0111 7
  35. #define b1000 8
  36. #define b1001 9
  37. #define b1010 10
  38. #define b1011 11
  39. #define b1100 12
  40. #define b1101 13
  41. #define b1110 14
  42. #define b1111 15
  43.  
  44. #define HEXSTART -1
  45. #define HEXDELIM -2
  46. #define HEXBAD   -3
  47.  
  48. /* build a hex digit value table with the bits inverted
  49.  */
  50.  
  51. static void initHexTable()
  52. { int a;
  53.  
  54.   for (a= 0; a < 256; a++)
  55.     HexTable[a]= HEXBAD;
  56.  
  57.   HexTable['0']= b0000;
  58.   HexTable['1']= b1000;
  59.   HexTable['2']= b0100;
  60.   HexTable['3']= b1100;
  61.   HexTable['4']= b0010;
  62.   HexTable['5']= b1010;
  63.   HexTable['6']= b0110;
  64.   HexTable['7']= b1110;
  65.   HexTable['8']= b0001;
  66.   HexTable['9']= b1001;
  67.   HexTable['A']= b0101; HexTable['a']= HexTable['A'];
  68.   HexTable['B']= b1101; HexTable['b']= HexTable['B'];
  69.   HexTable['C']= b0011; HexTable['c']= HexTable['C'];
  70.   HexTable['D']= b1011; HexTable['d']= HexTable['D'];
  71.   HexTable['E']= b0111; HexTable['e']= HexTable['E'];
  72.   HexTable['F']= b1111; HexTable['f']= HexTable['F'];
  73.   HexTable['x']= HEXSTART;
  74.   HexTable['\r']= HEXDELIM;
  75.   HexTable['\n']= HEXDELIM;
  76.   HexTable['\t']= HEXDELIM;
  77.   HexTable[' ']= HEXDELIM;
  78.   HexTable[',']= HEXDELIM;
  79.   HexTable['}']= HEXDELIM;
  80.  
  81.   Initialized = 1;
  82. }
  83.  
  84. /* read a hex value and return its value
  85.  */
  86.  
  87. static int nextInt(zf)
  88.      ZFILE *zf;
  89. { int c;
  90.   int value= 0;
  91.   int shift= 0;
  92.     
  93.   for (;;) {
  94.     c= zgetc(zf);
  95.     if (c == EOF)
  96.       return(-1);
  97.     else {
  98.       c= HexTable[c & 0xff];
  99.       switch(c) {
  100.       case HEXSTART:
  101.     shift= 0; /* reset shift counter */
  102.     break;
  103.       case HEXDELIM:
  104.     if (shift)
  105.       return(value);
  106.     break;
  107.       case HEXBAD:
  108.     return(-1);
  109.       default:
  110.     value += (c << shift);
  111.     shift += 4;
  112.       }
  113.     }
  114.   }
  115. }
  116.  
  117. static void badFile(name)
  118.      char *name;
  119. {
  120.   printf("%s: bad X bitmap file\n", name);
  121.   exit(1);
  122. }
  123.  
  124. Image *xbitmapLoad(fullname, name, verbose)
  125.      char         *fullname, *name;
  126.      unsigned int  verbose;
  127. { ZFILE        *zf;
  128.   Image        *image;
  129.   char          line[MAX_SIZE];
  130.   char          name_and_type[MAX_SIZE];
  131.   char         *type;
  132.   int           value;
  133.   int           v10p;
  134.   unsigned int  linelen, dlinelen;
  135.   unsigned int  x, y;
  136.   unsigned int  w, h;
  137.   byte         *dataptr;
  138.  
  139.   if (!Initialized)
  140.     initHexTable();
  141.  
  142.   if (! (zf= zopen(fullname)))
  143.     return(NULL);
  144.  
  145.   /* get width/height values */
  146.  
  147.   while (zgets(line, MAX_SIZE, zf)) {
  148.     if (strlen(line) == MAX_SIZE-1) {
  149.       fclose(zf);
  150.       return(NULL);
  151.     }
  152.  
  153.     /* width/height/hot_x/hot_y scanning
  154.      */
  155.  
  156.     if (sscanf(line,"#define %s %d", name_and_type, &value) == 2) {
  157.       if (!(type = rindex(name_and_type, '_')))
  158.     type = name_and_type;
  159.       else
  160.     type++;
  161.  
  162.       if (!strcmp("width", type))
  163.     w= (unsigned int)value;
  164.       if (!strcmp("height", type))
  165.     h= (unsigned int)value;
  166.     }
  167.  
  168.     /* if start of data, determine if it's X10 or X11 data and break
  169.      */
  170.  
  171.     if (sscanf(line, "static short %s = {", name_and_type) == 1) {
  172.       v10p = 1;
  173.       break;
  174.     }
  175.     if ((sscanf(line,"static unsigned char %s = {", name_and_type) == 1) ||
  176.     (sscanf(line, "static char %s = {", name_and_type) == 1)) {
  177.       v10p = 0;
  178.       break;
  179.     }
  180.   }
  181.  
  182.   if (!w || !h)
  183.     return(NULL);
  184.   image= newBitImage(w, h);
  185.  
  186.   /* get title of bitmap if any
  187.    */
  188.  
  189.   if ((type = rindex(name_and_type, '_')) && !strcmp("bits[]", type + 1)) {
  190.     *type= '\0';
  191.     image->title= dupString(name_and_type);
  192.   }
  193.     
  194.   /* read bitmap data
  195.    */
  196.  
  197.   linelen= (w / 8) + (w % 8 ? 1 : 0); /* internal line length */
  198.   if (v10p) {
  199.     dlinelen= (w / 8) + (w % 16 ? 2 : 0);
  200.     dataptr= image->data;
  201.     for (y= 0; y < h; y++) {
  202.       for (x= 0; x < dlinelen; x++) {
  203.     if ((value= nextInt(zf)) < 0) {
  204.       freeImage(image);
  205.       return(NULL);
  206.     }
  207.     *(dataptr++)= value >> 8;
  208.     if (++x < linelen)
  209.       *(dataptr++)= value & 0xff;
  210.       }
  211.     }
  212.   }
  213.   else {
  214.     dataptr= image->data;
  215.     for (y= 0; y < h; y++)
  216.       for (x= 0; x < linelen; x++) {
  217.     if ((value= nextInt(zf)) < 0)
  218.       badFile(name);
  219.     *(dataptr++)= value;
  220.       }
  221.   }
  222.  
  223.   if (verbose) {
  224.     printf("%s is a %dx%d X", name, image->width, image->height);
  225.     if (v10p)
  226.       printf("10");
  227.     else
  228.       printf("11");
  229.     if (image->title)
  230.       printf(" bitmap file titled '%s'", image->title);
  231.     printf("\n");
  232.   }
  233.   return(image);
  234. }
  235.  
  236. /* this is the easiest way to do this.  it's not likely we'll have mondo
  237.  * x bitmaps anyway given their size
  238.  */
  239.  
  240. int xbitmapIdent(fullname, name)
  241.      char         *fullname, *name;
  242. { Image *image;
  243.  
  244.   if (image= xbitmapLoad(fullname, name, 1)) {
  245.     freeImage(image);
  246.     return(1);
  247.   }
  248.   return(0);
  249. }
  250.