// include files ---------------
//
#include <stdio.h>
#include <malloc.h>
#include "bmpload.h"

typedef struct
{
  short   bfType;
  long    bfSize;
  short   bfReserved1;
  short   bfReserved2;
  long    bfOffBits;

  long    biSize;
  long    biWidth, biHeight;
  short   biPlanes, biBitCount;
  long    biCompression;
  long    biSizeImage;
  long    biXPelsPerMeter;
  long    biYPelsPerMeter;
  long    biClrUsed;
  long    biClrImportant;
} BitmapFileHeader;


BMPImage *BMP_Load( char *fn )
{
  printf( "loading \"%s\"... ", fn );

  FILE *f = fopen( fn, "rb" );
  if (!f) {
    perror("");
    return NULL;
  }

  BitmapFileHeader  bmfh;
  fread( &bmfh, 1, sizeof(bmfh), f );

  if  ((bmfh.bfType        != 0x4D42)||
       (bmfh.biBitCount    !=      8)||
       (bmfh.biCompression !=      0))
  {
    printf( "invalid format.\n" );
    return NULL;
  }

  if (bmfh.biHeight < 0)
    bmfh.biHeight = -bmfh.biHeight;

  BMPImage  *bm;
  bm = (BMPImage*)malloc(sizeof(BMPImage) + bmfh.biWidth*bmfh.biHeight);

  if (!bm) {
    printf( "out of memory.\n" );
    return  NULL;
  }
  bm->w      = bmfh.biWidth;
  bm->h      = bmfh.biHeight;
  bm->bmBits = (char*)((char*)bm + sizeof(BMPImage));

  printf( "%d x %d, ", bm->w, bm->h );

  fseek( f, bmfh.bfOffBits, SEEK_SET );

  for (int y=0; y < bm->h; y++) {
    fread( &( bm->bmBits[(bm->h-y-1) * bm->w] ), 1, bm->w, f );
  }

  fclose(f);

  printf( "ok.\n" );
  return  bm;
}
