/*

			Slide Show Screen Saver for Windows

					BMP Image Loader

*/

#include "screensv.h"

//  LOADBMPIMAGE  --  Load BMP image into memory

int loadBMPimage(FILE *input_file, HGLOBAL *LimageBitmap,
				   int *LsizeX, int *LsizeY)
{
	unsigned cmlen, bitlen;
	LPBITMAPINFOHEADER bh;
	HGLOBAL imageBitmap = NULL;			// In-memory bitmap
	BITMAPFILEHEADER bfh;

	if (fread(&bfh, sizeof bfh, 1, input_file) != 1) {
		loadError = "Error reading BMP file header";
		return FALSE;
	}

	if (memcmp(&bfh.bfType, "BM", 2) != 0) {
		loadError = "Bad file type in BMP file";
		return FALSE;
	}

	imageBitmap = malloc(bfh.bfSize);
	if (imageBitmap == NULL) {
		loadError = "Cannot allocate memory for BMP file";
		return FALSE;
	}

	bh = (LPBITMAPINFOHEADER) imageBitmap;

	if (fread(bh, sizeof bh->biSize, 1, input_file) != 1) {
		loadError = "No size in BMP header";
		return FALSE;
	}
	if (fread(((char *) bh) + sizeof bh->biSize, 1, bh->biSize - (sizeof bh->biSize), input_file) !=
			bh->biSize - (sizeof bh->biSize)) {
		loadError = "Error reading BMP file BITMAPINFO";
		return FALSE;
	}
	if (usePalette && (bh->biBitCount > 8) && (bh->biBitCount != 24)) {
		loadError = "16- and 32-bit/pixel BMPs unsupported in 256 colour mode; use JPG or PNG";
		return FALSE;
	}
	cmlen = (bh->biBitCount > 8) ? 0 :
		((bh->biClrUsed == 0 ? (1L << bh->biBitCount) : bh->biClrUsed) * sizeof(RGBQUAD));
	if (cmlen > 0) {
		if (fread(((char *) bh) + bh->biSize, 1, cmlen, input_file) != cmlen) {
			loadError = "Error reading BMP file colour map";
			return FALSE;
		}
	}

	fseek(input_file, bfh.bfOffBits, 0);
	bitlen = ((((((bh->biWidth * bh->biBitCount) / 8)  + (sizeof(LONG) - 1)) / sizeof(LONG)) * sizeof(LONG)) *
		 bh->biHeight);
	if (fread(((char *) bh) + bh->biSize + cmlen, 1, bitlen, input_file) != bitlen) {
		loadError = "Error reading BMP file bitmap data";
		return FALSE;
	}

	/*	If the display is 256 colour or the user has explicitly
		requested a palette-mapped image, transform full colour
		bitmaps into 256 colour replacements.  */

	if (usePalette && (bh->biBitCount > 8)) {
		HGLOBAL newBitmap = quantifyBMP(imageBitmap);

		GlobalFree(imageBitmap);
		if (newBitmap == NULL) {
			loadError = "Cannot create colour palette for true colour BMP file.";
			return FALSE;
		}
		imageBitmap = newBitmap;
		bh = (LPBITMAPINFOHEADER) imageBitmap;
	}

	*LsizeX = (int) bh->biWidth;
	*LsizeY = (int) bh->biHeight;
	*LimageBitmap = imageBitmap;
	return TRUE;
}