I am developing my own OS, with GNU-EFI, I am written a small BMP Image loader program.
I can Successfully read its headers and data ( not sure ) when I plot that on my Screen that is only showing blue color on pixels.
// Blue Pixels are Plotted BMP Image

How can I load this with Colours?
PlotPixel(x,y,color) Color takes Value as 0xFFFFFFFF;
Following is my bmp loader:
BMP.h
// bmp.h
#define WIN_BITMAP_SIGNATURE 0x4D42 // BM [ASCII]
#define BMP_HEADER_SIZE 54
#define DIB_HEADER_SIZE 40
#pragma pack(push, 1)
typedef struct
{
uint16_t bfType; // The characters "BM" - 2 Bytes
uint32_t bfSize; // The size of the file in bytes - 4 Bytes
uint16_t bfReserved1; // Unused - must be zero - 2 Bytes
uint16_t bfReserved2; // Unused - must be zero - 2 Bytes
uint32_t bfOffBits; // Offset to start of Pixel Data - 4 Bytes
uint32_t biSize; // DIB Header Size - 4 Bytes
int32_t biWidth; // Width - 4 Bytes
int32_t biHeight;
uint16_t biPlanes;
uint16_t biBitCount;
uint32_t biCompression;
uint32_t biSizeImage;
int32_t biXPexelsPerMeter;
int32_t biYPexelsPerMeter;
uint32_t biClrUsed;
uint32_t biClrImportant;
} BITMAP_HEADER;
typedef struct
{
BITMAP_HEADER* header;
uint8_t* data;
} BITMAP_IMG;
typedef struct
{
uint32_t red_mask;
uint32_t green_mask;
uint32_t blue_mask;
uint32_t alpha_mask;
uint32_t color_space_type;
uint32_t unused[16];
} BMPColorHeader;
#pragma pack(pop)
unsigned long createRGBA(int r, int g, int b, int a);
unsigned long createRGB(int r, int g, int b);
BITMAP_IMG* LoadBMPImage(EFI_FILE* Directory, CHAR16* Path, EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable);
BMP.c
// bmp.c
#include "bmp.h"
unsigned long createRGB(int r, int g, int b)
{
return ((r & 0xff) << 16) + ((g & 0xff) << 8) + (b & 0xff);
}
unsigned long createRGBA(int r, int g, int b, int a)
{
return ((r & 0xff) << 24) + ((g & 0xff) << 16) + ((b & 0xff) << 8)
+ (a & 0xff);
}
BITMAP_IMG* LoadBMPImage(EFI_FILE* Directory, CHAR16* Path, EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable)
{
EFI_FILE* BMPImage = LoadFile(Directory, Path, ImageHandle, SystemTable);
if(BMPImage == NULL) return NULL;
BITMAP_HEADER* BMPImageHeader;
SystemTable->BootServices->AllocatePool(EfiLoaderData, sizeof(BITMAP_HEADER), (void**)&BMPImageHeader);
UINTN size = sizeof(BITMAP_HEADER);
BMPImage->Read(BMPImage, &size, BMPImageHeader);
// Verify Signature
if(BMPImageHeader->bfType != WIN_BITMAP_SIGNATURE)
{
// Signature not Matched
Print(L"Signature Not Matched!");
Print(L"BMP Type [ Signature ] : ", BMPImageHeader->bfType);
return NULL;
}
else
{
Print(L"Signature Found");
}
if(BMPImageHeader->biBitCount == 32)
{
Print(L"BMP 32 Bit");
BMPColorHeader* BmpColor;
SystemTable->BootServices->AllocatePool(EfiLoaderData, sizeof(BMPColorHeader), (void**)&BmpColor);
UINTN size = sizeof(BITMAP_HEADER);
BMPImage->Read(BMPImage, &size, BmpColor);
// Check Color Header
if(0x00ff0000 != BmpColor->red_mask || 0x000000ff != BmpColor->blue_mask || 0x0000ff00 != BmpColor->green_mask)
{
Print(L"Unexpected Color Format");
}
if(0x73524742 != BmpColor->color_space_type)
{
Print(L"Unexcepted Color Space Type : %d", BmpColor->color_space_type);
}
}
else
{
Print(L"BMP Not 32 Bit : %d", BMPImageHeader->biBitCount);
}
uint8_t* BMPData;
{
BMPImage->SetPosition(BMPImage, sizeof(BITMAP_HEADER));
SystemTable->BootServices->AllocatePool(EfiLoaderData, size, (void**)&BMPData);
BMPImage->Read(BMPImage, &size, BMPData);
}
BITMAP_IMG* finishedImage;
SystemTable->BootServices->AllocatePool(EfiLoaderData, sizeof(BITMAP_IMG), (void**)&finishedImage);
finishedImage->header = BMPImageHeader;
finishedImage->data = BMPData;
int offset = 0;
int channels = finishedImage->header->biBitCount / 8;
for (int i = 0; i < finishedImage->header->biHeight; i++)
{
for (int j = 0; j < finishedImage->header->biWidth; j++)
{
//// I thinks following are wrong
// Red
int red = finishedImage->data[offset] & 0xFF;
int green = finishedImage->data[offset+1] & 0xFF;
int blue = finishedImage->data[offset+2] & 0xFF;
int alpha = 0x00;
// I thinks CreateRGBA can be also wrong
int hex_calculated = createRGBA(red, green, blue, alpha);
// This function is surely right ; It takes color value as 0xFFFFFFFF
PlotPixel(120+i, 120+j, hex_calculated);
offset += 3;
}
}
return finishedImage;
}