home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / xloadimg.zip / xloadimage.4.1 / xbitmap.c < prev    next >
C/C++ Source or Header  |  1993-10-21  |  5KB  |  256 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 <ctype.h>
  18. #include "image.h"
  19.  
  20. /* SUPPRESS 560 */
  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 == 4)
  105.           return(value << 4);
  106.     if (shift)
  107.       return(value);
  108.     break;
  109.       case HEXBAD:
  110.     return(-1);
  111.       default:
  112.     value += (c << shift);
  113.     shift += 4;
  114.       }
  115.     }
  116.   }
  117. }
  118.  
  119. static void badFile(name)
  120.      char *name;
  121. {
  122.   printf("%s: bad X bitmap file\n", name);
  123.   exit(1);
  124. }
  125.  
  126. Image *xbitmapLoad(fullname, name, verbose)
  127.      char         *fullname, *name;
  128.      unsigned int  verbose;
  129. { ZFILE        *zf;
  130.   Image        *image;
  131.   char          line[MAX_SIZE];
  132.   char          name_and_type[MAX_SIZE];
  133.   char         *type;
  134.   int           value;
  135.   int           v10p;
  136.   unsigned int  linelen, dlinelen;
  137.   unsigned int  x, y;
  138.   unsigned int  w = 0, h = 0;
  139.   byte         *dataptr;
  140.  
  141.   if (!Initialized)
  142.     initHexTable();
  143.  
  144.   if (! (zf= zopen(fullname)))
  145.     return(NULL);
  146.  
  147.   /* get width/height values */
  148.  
  149.   while (zgets((byte *)line, MAX_SIZE, zf)) {
  150.     if (strlen(line) == MAX_SIZE-1) {
  151.       zclose(zf);
  152.       return(NULL);
  153.     }
  154.  
  155.     /* width/height/hot_x/hot_y scanning
  156.      */
  157.  
  158.     if (sscanf(line,"#define %s %d", name_and_type, &value) == 2) {
  159.       if (!(type = rindex(name_and_type, '_')))
  160.     type = name_and_type;
  161.       else
  162.     type++;
  163.  
  164.       if (!strcmp("width", type))
  165.     w= (unsigned int)value;
  166.       if (!strcmp("height", type))
  167.     h= (unsigned int)value;
  168.     }
  169.  
  170.     /* if start of data, determine if it's X10 or X11 data and break
  171.      */
  172.  
  173.     if (sscanf(line, "static short %s = {", name_and_type) == 1) {
  174.       v10p = 1;
  175.       break;
  176.     }
  177.     if ((sscanf(line,"static unsigned char %s = {", name_and_type) == 1) ||
  178.     (sscanf(line, "static char %s = {", name_and_type) == 1)) {
  179.       v10p = 0;
  180.       break;
  181.     }
  182.   }
  183.  
  184.   if (!w || !h) {
  185.     zclose(zf);
  186.     return(NULL);
  187.   }
  188.   image= newBitImage(w, h);
  189.  
  190.   /* get title of bitmap if any
  191.    */
  192.  
  193.   if ((type = rindex(name_and_type, '_')) && !strcmp("bits[]", type + 1)) {
  194.     *type= '\0';
  195.     image->title= dupString(name_and_type);
  196.   }
  197.     
  198.   /* read bitmap data
  199.    */
  200.  
  201.   linelen= (w / 8) + (w % 8 ? 1 : 0); /* internal line length */
  202.   if (v10p) {
  203.     dlinelen= (w / 8) + (w % 16 ? 2 : 0);
  204.     dataptr= image->data;
  205.     for (y= 0; y < h; y++) {
  206.       for (x= 0; x < dlinelen; x++) {
  207.     if ((value= nextInt(zf)) < 0) {
  208.       freeImage(image);
  209.       zclose(zf);
  210.       return(NULL);
  211.     }
  212.     *(dataptr++)= value >> 8;
  213.     if (++x < linelen)
  214.       *(dataptr++)= value & 0xff;
  215.       }
  216.     }
  217.   }
  218.   else {
  219.     dataptr= image->data;
  220.     for (y= 0; y < h; y++)
  221.       for (x= 0; x < linelen; x++) {
  222.     if ((value= nextInt(zf)) < 0)
  223.       badFile(name);
  224.     *(dataptr++)= value;
  225.       }
  226.   }
  227.  
  228.   if (verbose) {
  229.     printf("%s is a %dx%d X", name, image->width, image->height);
  230.     if (v10p)
  231.       printf("10");
  232.     else
  233.       printf("11");
  234.     if (image->title)
  235.       printf(" bitmap file titled '%s'", image->title);
  236.     printf("\n");
  237.   }
  238.   zclose(zf);
  239.   return(image);
  240. }
  241.  
  242. /* this is the easiest way to do this.  it's not likely we'll have mondo
  243.  * x bitmaps anyway given their size
  244.  */
  245.  
  246. int xbitmapIdent(fullname, name)
  247.      char         *fullname, *name;
  248. { Image *image;
  249.  
  250.   if (image= xbitmapLoad(fullname, name, (unsigned int)1)) {
  251.     freeImage(image);
  252.     return(1);
  253.   }
  254.   return(0);
  255. }
  256.