/* xbmread.c  OpenGL read an xbm file                                       */
/*            given a filename.xbm, rgba, back_rgba,                        */
/*            returns width, height, rgba pixels                            */
/*     int width; int height; int RGBA; 0,0,0,0 used for background         */
/*     unsigned char pixels[4*width*height];                                */
/* call: status = xbmread("your-filename", rgba_foreground, rgba_background,*/
/*                         &width, &height, pixels);                        */
/* status==0 for OK                                                         */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static FILE *inp;        /* Pointer to the input FILE stream */
static int debug = 0;    /* set to 1 for full debug printout */
static int nrgba = 0;
static int lineno = -1;
static int aindex = 0;
static int lwidth = 0;
static int lheight = 0;
static int kwidth = 0;
static unsigned char line[256];
static int hexval(char ch);


int xbmread(char filename[], int rgba, int back_rgba, 
            int *width, int *height, int rgbapix[])
{
  int status = 0;
  int lineno = -1;
  int i, j, k, nbit;
  char h1, h2, ch, bits[8];
  char * p;
  
  nrgba = 0;
  nbit = 0;

  if(debug)printf("Display the header info within a XBM image file \n");

  /* Open the XBM image file */
  if ((inp = fopen(filename, "r")) == (FILE *)NULL)
  {
    if(debug) printf("xbmread: Cannot open file %s\n", filename);
    return -1;
  }

  /* Read the XBM image file header information */
  while(fgets(line, 255, inp)!=NULL)
  {
    if(debug) printf("%s", line);
    if(strlen(line)<5) continue; /* ignore junk lines */
    if(line[0]=='#')
    {
      if((p=strstr(line, "width"))!=NULL)
      {
        lwidth = atoi(p+5);
        if(debug) printf("found width=%d \n", lwidth);
      }
      else if((p=strstr(line, "height"))!=NULL)
      {
        lheight = atoi(p+6);
        if(debug) printf("found height=%d \n", lheight);
      }
    }
    else if((p=strstr(line, "static"))!=NULL)
    {
      lineno = lwidth * (lheight-1);
      if(debug) printf("found static \n");
    }
    else /* find  0xhh, sets of 8 bits */
    {
      for(i=0; i<strlen(line)-4; i++)
      {
        if(line[i]=='{') continue;
        if(line[i]==' ') continue;
        if(line[i]=='0' && (line[i+1]=='x' || line[i+1]=='X'))
        {
          h1 = hexval(line[i+2]);
          h2 = hexval(line[i+3]);
          ch = h1*16+h2;
          for( k=0; k<8; k++)
          {
            rgbapix[lineno+nrgba] = back_rgba;
            if( ch&(1<<k) ) rgbapix[lineno+nrgba] = rgba;
            nrgba++;
            if((nrgba)==lwidth)
            {
              nrgba = 0;
              lineno = lineno - lwidth;
              break; /* ignore left over bits */
            }
          }
          i = i+4; /* also skip comma */
        }
      }
    }  
  }
  fclose(inp);

  *width  = lwidth;
  *height = lheight; 
  return status;
} /* end xbmread */


static int hexval(char ch)
{
  static char hex[] = "0123456789ABCDEFabcdef";
  char *p;
  int val = 0;

  p = strchr(hex, ch);
  val = p-hex;
  val = (val>15)?val-6:val;
  return val;
} /* end hexval */


