/*
 * Utilities for manipulating bitmap and metafile images for
 * the purposes of conversion to RTF
 *
 */

char hexArray[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
  'C', 'D', 'E', 'F' };

void DecToHex(int dec, char *buf)
{
  int firstDigit = (int)(dec/16);
  int secondDigit = dec - (firstDigit*16);
  buf[0] = hexArray[firstDigit];
  buf[1] = hexArray[secondDigit];
  buf[2] = 0;
}
 
static unsigned int getshort(FILE *fp)
{
  int c, c1;
  c = getc(fp);  c1 = getc(fp);
  return ((unsigned int) c) + (((unsigned int) c1) << 8);
}

static unsigned int getint(FILE *fp)
{
  int c, c1, c2, c3;
  c = getc(fp);  c1 = getc(fp);  c2 = getc(fp);  c3 = getc(fp);
  return ((unsigned int) c) +
         (((unsigned int) c1) << 8) + 
	 (((unsigned int) c2) << 16) +
	 (((unsigned int) c3) << 24);
}

Bool GetBMPHeader(FILE *fp, int *Width, int *Height, int *Planes, int *BitsPerPixel)
{
  int          i, c, c1;
  unsigned int bfSize, bfOffBits, biSize, biWidth, biHeight, biPlanes;
  unsigned int biBitCount, biCompression, biSizeImage, biXPelsPerMeter;
  unsigned int biYPelsPerMeter, biClrUsed, biClrImportant;
//  char         *cmpstr;
  int         *pic24, *pic8;
//  char          buf[512];

  /* returns '1' on success */

  pic8 = pic24 = (int *) NULL;

/*
  fseek(fp, 0L, 2);      // figure out the file size
  filesize = ftell(fp);
  fseek(fp, 0L, 0);
*/

  /* read the file type (first two bytes) */
  c = getc(fp);  c1 = getc(fp);
  if (c!='B' || c1!='M') { return FALSE; }

  bfSize = getint(fp);
  getshort(fp);         /* reserved and ignored */
  getshort(fp);
  bfOffBits = getint(fp);

  biSize          = getint(fp);
  biWidth         = getint(fp);
  biHeight        = getint(fp);
  biPlanes        = getshort(fp);
  biBitCount      = getshort(fp);
  biCompression   = getint(fp);
  biSizeImage     = getint(fp);
  biXPelsPerMeter = getint(fp);
  biYPelsPerMeter = getint(fp);
  biClrUsed       = getint(fp);
  biClrImportant  = getint(fp);

  *Width = biWidth;
  *Height = biHeight;
  *Planes = biPlanes;
  *BitsPerPixel = biBitCount;

/*
  if (DEBUG>1) {
    fprintf(stderr,"\nLoadBMP:\tbfSize=%d, bfOffBits=%d\n",bfSize,bfOffBits);
    fprintf(stderr,"\t\tbiSize=%d, biWidth=%d, biHeight=%d, biPlanes=%d\n",
	    biSize, biWidth, biHeight, biPlanes);
    fprintf(stderr,"\t\tbiBitCount=%d, biCompression=%d, biSizeImage=%d\n",
	    biBitCount, biCompression, biSizeImage);
    fprintf(stderr,"\t\tbiX,YPelsPerMeter=%d,%d  biClrUsed=%d, biClrImp=%d\n",
	    biXPelsPerMeter, biYPelsPerMeter, biClrUsed, biClrImportant);
  }

  if (ferror(fp)) { bmpError(fname,"EOF reached in file header"); goto ERROR; }
*/

  /* error checking */
/*
  if ((biBitCount!=1 && biBitCount!=4 && biBitCount!=8 && biBitCount!=24) || 
      biPlanes!=1 || biCompression>BI_RLE4) {

    sprintf(buf,"Bogus BMP File!  (bitCount=%d, Planes=%d, Compression=%d)",
	    biBitCount, biPlanes, biCompression);

    bmpError(fname, buf);
    goto ERROR;
  }

  if (((biBitCount==1 || biBitCount==24) && biCompression != BI_RGB) ||
      (biBitCount==4 && biCompression==BI_RLE8) ||
      (biBitCount==8 && biCompression==BI_RLE4)) {

    sprintf(buf,"Bogus BMP File!  (bitCount=%d, Compression=%d)",
	    biBitCount, biCompression);

    bmpError(fname, buf);
    goto ERROR;
  }

*/
  
  /* skip ahead to colormap, using biSize */
  c = biSize - 40;    /* 40 bytes read from biSize to biClrImportant */
  for (i=0; i<c; i++) getc(fp);

  /* load up colormap, if any */

  if (biBitCount!=24) {
    int i, cmaplen;

    cmaplen = 1 << biBitCount;
    char dummyCh;
    for (i=0; i<cmaplen; i++) {
      dummyCh = getc(fp);
      dummyCh = getc(fp);
      dummyCh = getc(fp);
      getc(fp);         /* unused */
    }
  }
  
  /* load up the image */
//  if      (biBitCount == 1) rv = loadBMP1(fp,pic8,biWidth,biHeight);

  return TRUE;
}

static int scanLineWidth = 0;

Bool OutputBitmapHeader(FILE *fd, Bool isWinHelp = FALSE)
{
  int Width, Height, Planes, BitsPerPixel;
  if (!GetBMPHeader(fd, &Width, &Height, &Planes, &BitsPerPixel))
    return FALSE;

  scanLineWidth = (int)(Width/(8/BitsPerPixel));
  int goalW = 15*Width;
  int goalH = 15*Height;

  TexOutput("{\\pict");
  if (isWinHelp) TexOutput("\\wbitmap");
  else TexOutput("\\dibitmap");

  char buf[50];
  TexOutput("\\picw"); sprintf(buf, "%d", Width); TexOutput(buf);
  TexOutput("\\pich"); sprintf(buf, "%d", Height); TexOutput(buf);
  TexOutput("\\wbmbitspixel"); sprintf(buf, "%d", BitsPerPixel); TexOutput(buf);
  TexOutput("\\wbmplanes"); sprintf(buf, "%d", Planes); TexOutput(buf);
  TexOutput("\\wbmwidthbytes"); sprintf(buf, "%d", scanLineWidth); TexOutput(buf);
  TexOutput("\\picwgoal"); sprintf(buf, "%d", goalW); TexOutput(buf);
  TexOutput("\\pichgoal"); sprintf(buf, "%d", goalH); TexOutput(buf);
  TexOutput("\n");
  return TRUE;
}

Bool OutputBitmapData(FILE *fd)
{
  fseek(fd, 14, SEEK_SET);
  int bytesSoFar = 0;
  int ch = getc(fd);
  char hexBuf[3];
  while (ch != EOF)
  {
    if (bytesSoFar == scanLineWidth)
    {
      bytesSoFar = 0;
      TexOutput("\n");
    }
    DecToHex(ch, hexBuf);
    TexOutput(hexBuf);
    bytesSoFar ++;
    ch = getc(fd);
  }
  TexOutput("\n}\n");
  return TRUE;
}
