/* Copyright (c) 2010 MJ Rutter 
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA  02110-1301, USA.
 */ 

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

#include "bmp2eps.h"

/* PBM reader, both binary and ASCII forms
 *
 * MJR 9/02, 6/10
 */

void pbmadata(FILE *pnm, int width, int height, unsigned char *data);

void pbmread(FILE *pbm, struct bitmap *image_out,int binary)
{
  int i,debug;

  unsigned int width,height,data_len,scan_len;
  unsigned char *image;
  unsigned int data[2];

  debug=image_out->flags&DEBUG_MASK;
  if (debug) fprintf(stderr,"PBM file detected\n");
  
  pnmheader(pbm,2,data);

  width=data[0];
  height=data[1];

  if(debug)fprintf(stderr,"Image width=%d, height=%d\n",width,height);

  scan_len=width>>3;
  if (width&7) scan_len++;

  data_len=height*scan_len;

  if (!(image=malloc(data_len))){
    fprintf(stderr,"Error in malloc\n");
    exit(1);
  }

  if (binary){
    i=fread(image,1,data_len,pbm);
    if (i!=data_len){
      fprintf(stderr,"Error reading file: %d bytes read, %d expected\n",
	      i,data_len);
      exit(1);
    }

    /* We now have 1 for black and 0 for white. We wanted the opposite */

    for(i=0;i<data_len;i++) image[i]=~image[i];
  }
  else {
    if (debug>1) fprintf(stderr,"ASCII pbm file being read\n");
    pbmadata(pbm,width,height,image);
  }

  image_out->data=image;
  image_out->data_len=data_len;
  image_out->height=height;
  image_out->width=width;
  image_out->depth=1;
  image_out->type=BMP;
  image_out->colour=GREY;
}

/* Read ASCII version of pgm file, data section only
 *
 * Two problems: whitespace between items is optional
 *               padding to integer number of bytes per row is not done,
 *                 but bmp2eps's internal format requires
 */

void pbmadata(FILE *pnm, int width, int height, unsigned char *data){
  int i,k,c,chunk,line;
  unsigned char *dptr;
  unsigned char byte;

  dptr=data;

  for(i=0;i<height;i++){  

    line=0;
    while(line<width){
      chunk=width-line;
      if (chunk>8) chunk=8;
      byte=0;
      k=0;
      while(((c=getc(pnm))!=EOF)&&(k<chunk)){
	if ((c==' ')||(c==9)||(c==10)||(c==13)) continue;
        if (c=='1')
	  byte<<=1;
        else if (c=='0')
	  byte=(byte<<1)+1;
	else{
	  fprintf(stderr,"Unexpected character %c in input\n",c);
	  exit(1);
	}
	k++;
      }
      if (k==8) *(dptr++)=byte;
      else *(dptr++)=byte<<(8-k);
      line+=k;
      if ((c==EOF)&&(line<width)&&(i+1<width)){
	fprintf(stderr,"Unexpected EOF in pbma read\n");
	exit(1);
      }
    }
  }
}
