Avatar of PMH4514
PMH4514

asked on 

C++ bitmap question

I have this chunk of code that writes out a bmp file from supplied data. (See snippet) It functions propertly.

How is this code best transformed so that instead it returns an HBITMAP for use in MFC, given the exact same parameters? (minus the filename of course)

int write8BitBmpFile(char *filename, unsigned int width, unsigned int height, 
					 unsigned char *image)
{
	BITMAPINFOHEADER bmpInfoHeader;
	BITMAPFILEHEADER bmpFileHeader;
	FILE *filep;
	unsigned int row;
	unsigned int extrabytes, bytesize;
	unsigned char *paddedImage = NULL;
	RGBQUAD palette[256];
	unsigned int i;
	unsigned int numPaletteEntries = 256;
 
 
	// Create the palette - each pixel is an index into the palette
	for (i = 0; i < numPaletteEntries; i++) {
		palette[i].rgbRed = i;
		palette[i].rgbGreen = i;
		palette[i].rgbBlue = i;
		palette[i].rgbReserved = 0;
	}
 
 
 
	/* The .bmp format requires that the image data is aligned on a 4 byte boundary.  For 8 - bit bitmaps,
	this means that the width of the bitmap must be a multiple of 4. This code determines
	the extra padding needed to meet this requirement. */
	extrabytes = (4 - width % 4) % 4;
 
 
	// This is the size of the padded bitmap
	bytesize = (width + extrabytes) * height;
 
 
	// Fill the bitmap file header structure
	bmpFileHeader.bfType = 'MB';   // Bitmap header
	bmpFileHeader.bfSize = 0;      // This can be 0 for BI_RGB bitmaps
	bmpFileHeader.bfReserved1 = 0;
	bmpFileHeader.bfReserved2 = 0;
	bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * numPaletteEntries;
 
 
	// Fill the bitmap info structure
	bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmpInfoHeader.biWidth = width;
	bmpInfoHeader.biHeight = height;
	bmpInfoHeader.biPlanes = 1;
	bmpInfoHeader.biBitCount = 8;            // 8 - bit bitmap
	bmpInfoHeader.biCompression = BI_RGB;
	bmpInfoHeader.biSizeImage = bytesize;     // includes padding for 4 byte alignment
	bmpInfoHeader.biXPelsPerMeter = 0;
	bmpInfoHeader.biYPelsPerMeter = 0;
	bmpInfoHeader.biClrUsed = numPaletteEntries;
	bmpInfoHeader.biClrImportant = 0;
 
 
 
 
	// Open file
	if ((filep = fopen(filename, "wb")) == NULL) {
		printf("Error opening file %s\n", filename);
		return FALSE;
	}
 
 
	// Write bmp file header
	if (fwrite(&bmpFileHeader, 1, sizeof(BITMAPFILEHEADER), filep) < sizeof(BITMAPFILEHEADER)) {
		printf("Error writing bitmap file header\n");
		fclose(filep);
		return FALSE;
	}
 
 
	// Write bmp info header
	if (fwrite(&bmpInfoHeader, 1, sizeof(BITMAPINFOHEADER), filep) < sizeof(BITMAPINFOHEADER)) {
		printf("Error writing bitmap info header\n");
		fclose(filep);
		return FALSE;
	}
 
 
	// Write bmp palette
	if (fwrite(palette, 1, numPaletteEntries * sizeof(RGBQUAD), filep) < numPaletteEntries * sizeof(RGBQUAD)) {
		printf("Error writing bitmap palette\n");
		fclose(filep);
		return FALSE;
	}
 
 
	// Allocate memory for some temporary storage
	paddedImage = (unsigned char *)calloc(sizeof(unsigned char), bytesize);
	if (paddedImage == NULL) {
		printf("Error allocating memory \n");
		fclose(filep);
		return FALSE;
	}
 
 
	/* Flip image - bmp format is upside down.  Also pad the paddedImage array so that the number
	of pixels is aligned on a 4 byte boundary. */
	for (row = 0; row < height; row++)
		memcpy(&paddedImage[row * (width + extrabytes)], &image[(height - 1 - row) * width], width);
 
	// Write bmp data
	if (fwrite(paddedImage, 1, bytesize, filep) < bytesize) {
		printf("Error writing bitmap data\n");
		free(paddedImage);
		fclose(filep);
		return FALSE;
	}
 
 
	// Close file
	fclose(filep);
	free(paddedImage);
	return TRUE;
}

Open in new window

System ProgrammingC++

Avatar of undefined
Last Comment
PMH4514

8/22/2022 - Mon