/* bitmap_2bit.c
 * 
 * 
 */ 

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

#include "def.h"
#include "bitmap_2bit.h"

/*
 * LOCAL functions
 */

static int isValidCoords(Bitmap_2bit *bitmap, int x, int y) {
  return ( (0 <= x && x < bitmap->width ) &&
	   (0 <= y && y < bitmap->height)    );
}
	  
/*
 * PUBLIC functions
 */
int bitmapSize_bmp2bit(Bitmap_2bit *bitmap) {
  int size = (bitmap->width*bitmap->height) / 8;
  if( ((bitmap->width*bitmap->height)%8) > 0)
    size++;
  return size;
} 

Bitmap_2bit * create_bmp2bit(int width, int height) {
  Bitmap_2bit *bitmap;
  int size;

  bitmap = malloc( sizeof(Bitmap_2bit) );
  if(bitmap == NULL) {
    return NULL;
  }
  bitmap->width  = width;
  bitmap->height = height;
  
  size = bitmapSize_bmp2bit(bitmap);


  bitmap->image = calloc(size, sizeof(unsigned char) );
  if( bitmap->image == NULL ) {
    free(bitmap);
    return NULL;
  }

  return bitmap;
}


/* Pikselit ovat päinvastaisessa järjestyksessä byten sisällä */

void setPixel_bmp2bit(Bitmap_2bit *bitmap, 
		      int x, int y, int value) {
  int byteP;
  int bitP;
  unsigned char mask = 0;
  
  if( ! isValidCoords(bitmap, x, y) ) 
    return;

  byteP = ( (y*bitmap->width) + x ) / 8;
  bitP = 7 - (( (y*bitmap->width) + x ) % 8); /* Reverse order inside byte */

  if( value == 0 ) {
    mask = 1 << bitP;
    mask = ~mask;
    bitmap->image[byteP] &= mask;
  }
  else {
    mask = 1 << bitP;
    bitmap->image[byteP] |= mask;
  }

}

/* Pikselit ovat päinvastaisessa järjestyksessä byten sisällä */

int getPixel_bmp2bit(Bitmap_2bit *bitmap,
		     int x, int y) {
  int byteP;
  int bitP;
  unsigned char mask = 0;

  assert( isValidCoords(bitmap, x, y) ); 
  
  byteP = ( (y*bitmap->width) + x ) / 8;
  bitP = 7- (( (y*bitmap->width) + x ) % 8); /* reverse order inside byte */
  
  mask = 1 << bitP;
  
  return ( bitmap->image[byteP] & mask ) > 0;
}


int writeToFile_bmp2bit(Bitmap_2bit *bitmap, char *filename) {
  FILE *file;
  
  file = fopen(filename, "w");
  if(file == NULL) {
    perror( filename );
    return FALSE;
  }
    
  /* Header information */
  fprintf(file,"P4\n %d %d\n",bitmap->width,bitmap->height);
  

  fwrite( bitmap->image, 
	  sizeof(unsigned char), bitmapSize_bmp2bit(bitmap), file);
  
  fclose(file);

  return TRUE;
}


