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