// http://astronomy.swin.edu.au/~pbourke/dataformats/bmp/

#include "stdio.h"

// BMP Header:

typedef struct {
  unsigned char type[2];                   /*      BM Magic identifier    */
  unsigned int size;                       /* 2359350 File size in bytes  */
  unsigned short int reserved1, reserved2; /*     0,0                     */
  unsigned int offset;                     /*      54 Offset to image data, bytes */
} BMPHeader;

// BMP image information header

typedef struct {
  unsigned int size;               /*         40 Header size in bytes      */
  int width,height;                /*  1024, 768 Width and height of image */
  unsigned short int planes;       /*          1 Number of colour planes   */
  unsigned short int bits;         /*         24  Bits per pixel           */
  unsigned int compression;        /*          0  Compression type         */
  unsigned int imagesize;          /*    2359296  Image size in bytes      */
  int xresolution,yresolution;     /* 3937, 3937  Pixels per meter         */
  unsigned int ncolours;           /*   16777216  Number of colours        */
  unsigned int importantcolours;   /*   16777216  Important colours        */
} BMPInfoHeader;

void drawZone1(int iX, int iY, unsigned char oColor[3]);
void drawZone2(int iX, int iY, unsigned char oColor[3]);
void drawZone3(int iX, int iY, unsigned char oColor[3]);
void drawZone4(int iX, int iY, unsigned char oColor[3]);
void drawZone5(int iX, int iY, unsigned char oColor[3]);
void drawZone6(int iX, int iY, unsigned char oColor[3]);
void drawBlank(unsigned char oColor[3]);

int main()
{
   unsigned char lHead[14];
   BMPInfoHeader lInfoHead;
   unsigned char lColor[3];
   int x,y;
   int lX1 = 0, lX2 = 256, lX3 = 512, lX4 = 768, lX5 = 1024;
   int lY1 = 0, lY2 = 256, lY3 = 512,lY4 = 768;


	lHead[ 0] = 'B';
	lHead[ 1] = 'M';
	lHead[ 2] = '\x36';
	lHead[ 3] = '\0';
	lHead[ 4] = '\x24';
	lHead[ 5] = '\x00';
	lHead[ 6] = '\x00';
	lHead[ 7] = '\x00';
	lHead[ 8] = '\x00';
	lHead[ 9] = '\x00';
	lHead[10] = '\x36';
	lHead[11] = '\x00';
	lHead[12] = '\x00';
	lHead[13] = '\x00';

	lInfoHead.size = 40;
	lInfoHead.width = 1024;
	lInfoHead.height = 768;
	lInfoHead.planes = 1;
	lInfoHead.bits = 24;
	lInfoHead.compression = 0;
	lInfoHead.imagesize = 2359296;
	lInfoHead.xresolution = 3937;
	lInfoHead.yresolution = 3937;
	lInfoHead.ncolours = 16777216;
	lInfoHead.importantcolours = 16777216;
	FILE *lTheOutput = fopen("colorcube.bmp","wb");
	if ( lTheOutput == NULL)
      return 0;
	fwrite(lHead, 1,14, lTheOutput);
	fwrite(&lInfoHead, 1, 40, lTheOutput);

	for ( y=0; y < 768; y++)
	{
		for ( x=0; x< 1024; x++)
		{
			if      ( x>=lX3 && x < lX4 && y <  lY2            )    
				drawZone1(x-lX3, y, lColor);
			else if (           x < lX2 && y >= lY2 && y < lY3 )    
				drawZone2(x    , y-lY2, lColor);
			else if ( x>=lX2 && x < lX3 && y >= lY2 && y < lY3 )    
				drawZone3(x-lX2, y-lY2, lColor);
			else if ( x>=lX3 && x < lX4 && y >= lY2 && y < lY3 )    
				drawZone4(x-lX3, y-lY2, lColor);
			else if ( x>=lX4            && y >= lY2 && y < lY3 )    
				drawZone5(x-lX4, y-lY2, lColor);
			else if ( x>=lX3 && x < lX4 && y >= lY3 )               
				drawZone6(x-lX3, y-lY3, lColor);
			else
				drawBlank(lColor);
			fwrite(&lColor, 1,3, lTheOutput);
       }
   }
   fclose(lTheOutput);
   return 0;
}


void drawZone1(int iX, int iY, unsigned char oColor[3])
{
   oColor[2] = 0; //Red
   oColor[1] = iX; //Green
   oColor[0] = 255-iY; //Blue
}

void drawZone2(int iX, int iY, unsigned char oColor[3])
{
   oColor[2] = iY; //Red
   oColor[1] = 255-iX; //Green
   oColor[0] = 255; //Blue
}

void drawZone3(int iX, int iY, unsigned char oColor[3])
{
   oColor[2] = iY; //Red
   oColor[1] = 0; //Green
   oColor[0] = 255-iX; //Blue
}

void drawZone4(int iX, int iY, unsigned char oColor[3])
{
   oColor[2] = iY; //Red
   oColor[1] = iX; //Green
   oColor[0] = 0; //Blue
}

void drawZone5(int iX, int iY, unsigned char oColor[3])
{
   oColor[2] = iY; //Red
   oColor[1] = 255; //Green
   oColor[0] = iX; //Blue
}

void drawZone6(int iX, int iY, unsigned char oColor[3])
{
   oColor[2] = 255; //Red
   oColor[1] = iX; //Green
   oColor[0] = iY; //Blue
}

void drawBlank(unsigned char oColor[3])
{
   oColor[2] = 255; //Red
   oColor[1] = 255; //Green
   oColor[0] = 255; //Blue
}









