#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "_bmp.h"

int
main( int argc, char **argv ) {
  unsigned char *rgb, *p;
  int width, height, x, y, i, isize;

  argc = argc; // avoid unused compiler warnings
  argv = argv;
  for( width = 100; width < 104; width++ ) {
    height = 100;
    rgb = (unsigned char *)calloc( width * height * 3, 1 );
    p = rgb;
    isize = width >> 2;
    for( y = 0; y < height; y++ ) {
      x = 0;
      for( i = 0; i < isize; i++, p += 3 ) {
        p[ 0 ] = 255 - y;     // red
        p[ 1 ] = 0;           // green 
        p[ 2 ] = 0;           // blue 
      }
      x += isize;
      for( i = 0; i < isize; i++, p += 3 ) {
        p[ 0 ] = 0;           // red
        p[ 1 ] = 255 - y;     // green 
        p[ 2 ] = 0;           // blue 
      }
      x += isize;
      for( i = 0; i < isize; i++, p += 3 ) {
        p[ 0 ] = 0;           // red
        p[ 1 ] = 0;           // green 
        p[ 2 ] = 255 - y;     // blue 
      }
      x += isize;
      for( ; x < width; x++, p += 3 ) {
        p[ 0 ] = 255 - y;     // red
        p[ 1 ] = 255 - y;     // green
        p[ 2 ] = 255 - y;     // blue
      }
    }
    char filename[ 100 ];
    sprintf( filename, "test_%dx%d.bmp", width, height );
    _BMPWriteRGB( filename, rgb, width*3, 0, 0, width, height );
    free( rgb );
    
    int ret_value;
    int ret_width, ret_height, ret_depth;
    unsigned char *ret_image, *ret_palette;
    ret_width = ret_height = ret_depth = -1;
    ret_image = ret_palette = NULL; 
    ret_value = _BMPRead( filename, &ret_width, &ret_height, &ret_depth, &ret_image,
                              &ret_palette );
    if( ret_value != 0 ) {
      printf( "Error! _BMPReadFile( '%s' ) rgb failed with code %d\n", filename, ret_value );
      continue;
    }
    assert( ret_width == width );
    assert( ret_height == height );
    assert( ret_depth == 24 );
    assert( ret_palette == NULL );
    p = ret_image;
    for( y = 0; y < height; y++ ) {
      for( i = 0; i < isize; i++, p += 3 ) {
        assert( p[ 0 ] == 255 - y );     // red
        assert( p[ 1 ] == 0 );           // green 
        assert( p[ 2 ] == 0 );           // blue 
      }
      for( i = 0; i < isize; i++, p += 3 ) {
        assert( p[ 0 ] == 0 );           // red
        assert( p[ 1 ] == 255 - y );     // green 
        assert( p[ 2 ] == 0 );           // blue 
      }
      for( i = 0; i < isize; i++, p += 3 ) {
        assert( p[ 0 ] == 0 );           // red
        assert( p[ 1 ] == 0 );           // green 
        assert( p[ 2 ] == 255 - y );     // blue 
      }
      for( x = 3 * isize; x < width; x++, p += 3 ) {
        assert( p[ 0 ] == 255 - y );     // red
        assert( p[ 1 ] == 255 - y );     // green
        assert( p[ 2 ] == 255 - y );     // blue
      }
    }

    unsigned char *pixels = (unsigned char *)calloc( width * height, 1 );
    p = pixels;
    isize = width >> 1;
    for( y = 0; y < height; y++ ) {
      for( x = 0; x < isize; x++ ) *(p++) = y;
      for( ; x < width; x++ ) *(p++) = 255 - y;
    }
    sprintf( filename, "test_gray_%dx%d.bmp", width, height );
    _BMPWriteGray( filename, pixels, width, 0, 0, width, height );
    free( pixels );

    ret_width = ret_height = ret_depth = -1;
    ret_image = ret_palette = NULL; 
    ret_value = _BMPRead( filename, &ret_width, &ret_height, &ret_depth, &ret_image,
                              &ret_palette );
    if( ret_value != 0 ) {
      printf( "Error! _BMPRead( '%s' ) gray failed with code %d\n", filename, ret_value );
      continue;
    }
    assert( ret_width == width );
    assert( ret_height == height );
    assert( ret_depth == 8 );
    assert( ret_image != NULL );
    assert( ret_palette != NULL );
    p = ret_palette;
    for( i = 0; i < 256; i++, p += 3 ) {
      assert( p[ 0 ] == i ); // red
      assert( p[ 1 ] == i ); // green
      assert( p[ 2 ] == i ); // blue
    }
    p = ret_image;
    for( y = 0; y < height; y++ ) {
      for( x = 0; x < isize; x++, p++ ) assert( *p == y );
      for( ; x < width; x++, p++ ) assert( *p == 255 - y );
    }
  }

  return( 0 );
}

