/*	
 *	clipbmp.h
 *
 *	Windows Bitmap
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2018 Naoyuki Sawa
 *
 *	* Sun May 20 23:59:59 JST 2018 Naoyuki Sawa
 *	- 1st リリース。
 *	  今回は、P/ECE標準の4階調画面を保存する目的で、最小限の機能だけを作成しました。
 *	  今後、必要に応じて、2階調や16階調の画像も保存出来るように、機能を拡張しようと思います。(※TODO:)
 */
#include "clip.h"
//*****************************************************************************
//	ローカル関数
//*****************************************************************************
static char* complete_extension(char* dstPath, const char* srcPath, const char* defExt) {
	char drive[MAX_DRIVE], dir[MAX_DIR], fname[MAX_FNAME], ext[MAX_EXT];
	splitpath(srcPath, drive, dir, fname, ext);
	makepath(dstPath, drive, dir, fname, (*ext ? ext : defExt));
	return dstPath;
}
//*****************************************************************************
//	グローバル関数
//*****************************************************************************
void bmp_save(const char* path/*拡張子省略可*/, int w, int h, int (*fnPoint)(int x, int y, void* arg), void* arg) {
	char tmpPath[MAX_PATH];
	FILE* fp = fopen(complete_extension(tmpPath, path, "bmp"), "wb");
	if(!fp) { DIE(); }
	bmp_dump(fp, w, h, fnPoint, arg);
	fclose(fp);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void bmp_dump(FILE* fp, int w, int h, int (*fnPoint)(int x, int y, void* arg), void* arg) {
	uint8_t bmp[] = {
		//BITMAPINFOHEADER
		0x42,0x4D,		// 0 bfType
		0x00,0x00,0x00,0x00,	// 2 bfSize		←書き換える。
		0x00,0x00,		// 6 bfReserved1
		0x00,0x00,		// 8 bfReserved2
		0x00,0x00,0x00,0x00,	//10 bfOffBits		←書き換える。
		//BITMAPINFOHEADER
		0x28,0x00,0x00,0x00,	//14 biSize
		0x00,0x00,0x00,0x00,	//18 biWidth		←書き換える。
		0x00,0x00,0x00,0x00,	//22 biHeight		←書き換える。
		0x01,0x00,		//26 biPlanes
		0x08,0x00,		//28 biBitCount
		0x00,0x00,0x00,0x00,	//30 biCompression
		0x00,0x00,0x00,0x00,	//34 biSizeImage
		0x00,0x00,0x00,0x00,	//38 biXPixPerMeter
		0x00,0x00,0x00,0x00,	//42 biYPixPerMeter
		0x05,0x00,0x00,0x00,	//46 biClrUsed
		0x00,0x00,0x00,0x00,	//50 biCirImportant
		//RGBQUAD
		0xFF,0xFF,0xFF,0x00,	//54 bmiColors[0]	COLOR_WHITE
		0xAA,0xAA,0xAA,0x00,	//58 bmiColors[1]	COLOR_GLAY_W
		0x55,0x55,0x55,0x00,	//62 bmiColors[2]	COLOR_GLAY_B
		0x00,0x00,0x00,0x00,	//66 bmiColors[3]	COLOR_BLACK
		0x00,0xFF,0x00,0x00,	//70 bmiColors[4]	COLOR_MASK
	};
	int pitch     = (w + 3) & ~3;
	int bfSize    = sizeof bmp + (pitch * h);
	int bfOffBits = sizeof bmp;
	PUT_LEWORD(&bmp[ 2], bfSize);
	PUT_LEWORD(&bmp[10], bfOffBits);
	PUT_LEWORD(&bmp[18], w);
	PUT_LEWORD(&bmp[22], h);
	if(fwrite(bmp, 1, sizeof bmp, fp) != sizeof bmp) { DIE(); }
	{
		uint8_t* buf = calloc(pitch, 1);
		if(!buf) { DIE(); }
		{
			int y;
			for(y = h - 1; y >= 0; y--) {
				int x;
				for(x = 0; x < w; x++) {
					int c = (*fnPoint)(x, y, arg);
					if((unsigned)c > 4) { c = 4; }
					buf[x] = c;
				}
				if(fwrite(buf, 1, pitch, fp) != (size_t)pitch) { DIE(); }
			}
		}
		free(buf);
	}
}
