/*****************************************************************
 * flface.c: FBM Release 1.0 25-Feb-90 Michael Mauldin
 *
 * Copyright (C) 1989,1990 by Michael Mauldin.  Permission is granted
 * to use this file in whole or in part for any purpose, educational,
 * recreational or commercial, provided that this copyright notice
 * is retained unchanged.  This software is available to all free of
 * charge by anonymous FTP and in the UUNET archives.
 *
 * flface.c: 
 *
 * CONTENTS
 *	write_face (image, stream)
 *	read_face (image, stream, mstr, mlen)
 *	
 *
 * EDITLOG
 *	LastEditDate = Mon Jun 25 00:07:38 1990 - Michael Mauldin
 *	LastFileName = /usr2/mlm/src/misc/fbm/flface.c
 *
 * HISTORY
 * 25-Jun-90  Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
 *	Package for Release 1.0
 *
 * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
 *	Beta release (version 0.9) mlm@cs.cmu.edu
 *
 * 12-Nov-88  Michael Mauldin (mlm) at Carnegie-Mellon University
 *	Created.
 *****************************************************************/

# include <stdio.h>
# include <math.h>
# include <ctype.h>
# include "fbm.h"

/****************************************************************
 * write_face: Write Bennet Yee's face file format
 ****************************************************************/

#ifndef lint
static char *fbmid =
"$FBM flface.c <1.0> 25-Jun-90  (C) 1989,1990 by Michael Mauldin, source \
code available free from MLM@CS.CMU.EDU and from UUNET archives$";
#endif

write_face (image, stream)
FBM *image;
FILE *stream;
{ register int r, c, word, width, height;
  register unsigned char *bm;

  width = image->hdr.cols;
  height = image->hdr.rows;

  put_short (BM_MAGIC, stream, BIG);
  put_short (width, stream, BIG);
  put_short (height, stream, BIG);
  
  for (r=0; r<height; r++)
  { word = 0;
    bm = &(image->bm[r * image->hdr.rowlen]);

    for (c=0; c<width; c++)
    { word = (word >> 1) | (*bm++ ? 0: ((1 << 15)));
      if ((c&15) == 15) put_short (word, stream, BIG);
    }

    if (c&15)
    { word >>= (16 - (c&15));
      put_short (word, stream, BIG);
    }
  }
  
  return (1);
}

/****************************************************************
 * read_face: Read Bennet Yee's FACE format
 ****************************************************************/

read_face (image, rfile, mstr, mlen)
FBM *image;
FILE *rfile;
char *mstr;
int mlen;
{ register unsigned char *bmp;
  register int r, c, word, width, height, rowlen, magic;

  magic =  (NEXTMCH(rfile,mstr,mlen) & 0xff) << 8;
  magic |= (NEXTMCH(rfile,mstr,mlen) & 0xff);

  if (magic != BM_MAGIC)
  { fprintf (stderr, "Bad magic number %04x, not BM format\n", magic);

    fprintf (stderr, "Next 10 chars:");
    for (r=0; r<10; r++)
    { c = fgetc (rfile); fprintf (stderr, " %03o", c); }
    fprintf (stderr, "\n");
    return (0);
  }
  
  width = get_short (rfile, BIG);
  height = get_short (rfile, BIG);
  
  if (width > 5000 || height > 5000)
  { fprintf (stderr, "Image too big, bogus width %d or height %d maybe?\n",
	     width, height);
    return (0);
  }

  /* Initialize FBM header and allocate memory for bitmap */
  image->hdr.cols = width;
  image->hdr.rows = height;
  image->hdr.planes = 1;
  image->hdr.bits = 1;
  image->hdr.physbits = 8;
  image->hdr.rowlen = 16 * ((image->hdr.cols + 15) / 16);
  image->hdr.plnlen = image->hdr.rowlen * image->hdr.rows;
  image->hdr.clrlen = 0;
  image->hdr.aspect = 1.0;
  image->hdr.title[0] = 0;
  image->hdr.credits[0] = 0;

  alloc_fbm (image);

  /* Now read bits and store them in the proper place in the bitmap */
  rowlen = image->hdr.rowlen;

  
  for (r=0; r<height; r++)
  { bmp = &(image->bm[r * rowlen]);

    for (c=0; c<width; c++)
    { if ((c&15) == 0 && (word = get_short (rfile, BIG)) == EOF)
      { fprintf (stderr, "r %d, c %d\n", r, c);
        return (0);
      }

      *bmp++ = ((word & 1) ? BLACK : WHITE);
      word >>= 1;
    }
  }
  
  return (1);
}
