0x42, 0x4D
The first 2 bytes are B and M, that's just the bitmap file header which is 54 bytes in total. It's not part of the first row.
The size is 0x7B x 0x5A pixels
Towards the end you have 0x18 0x00 which is 24, for 24-bit bitmap, not 16-bit
So you have to skip 54 byte, and read as 24-bit
int width_in_bytes = ((width * 24 + 31) / 32) * 4 * height;
for(int row = height - 1; row >= 0; row--)
{
for(int col = 0; col < width; col++)
{
int i = row * width_in_bytes + col * 3;
unsigned char blu = bitmap[54 + i + 0];
unsigned char grn = bitmap[54 + i + 1];
unsigned char red = bitmap[54 + i + 2];
int pixel = red | ((uint16_t)grn << 8) | ((uint32_t)blu << 16);
SetPixel(row, col, pixel);
}
}
If the device is expecting 16-bit bitmap, then try to obtain 16-bit bitmap in the first place. For example when taking screen shot, Windows allows 16-bit format.
SDL supports SDL_PIXELFORMAT_RGB565 as well. GDI+ is another option if you are coding in Windows.
If your source bitmap is 24-bit, and you want to convert to 16-bit 565 format, write the formula based on the MCVE below
24-bit bitmap has color range from 0-255, whereas 16-bit has color range from 0-31 (0-63 for green in the case of 565 format). You have to normalize the color, for example by multiplying the red value by 31/255. And then shift the values to put in 16-bit integer.
16-bit bitmap format expects 3 colors (a total of 12 bytes) before the pixels start. These colors contain information about 565 format.
#include <Windows.h>
#include <stdint.h>
#include <iostream>
#include <fstream>
#include <vector>
int main()
{
HBITMAP hbitmap = (HBITMAP)LoadImage(NULL, "24bit.bmp",
IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if(!hbitmap)
return 0;
BITMAP bm;
GetObject(hbitmap, sizeof(bm), &bm);
if(bm.bmBitsPixel != 24)
{
DeleteObject(hbitmap);
std::cout << "Expecting 24-bit bitmap\n";
return 0;
}
BYTE *source = (BYTE*)bm.bmBits;
int w = bm.bmWidth;
int h = bm.bmHeight;
//calculate width in bytes (wb) for source and destination
DWORD wb_src = ((w * 24 + 31) / 32) * 4;
DWORD wb_dst = ((w * 16 + 31) / 32) * 4;
int size = wb_dst * h;
std::vector<BYTE> dest(size);
for(int r = 0; r < h; r++)
{
for(int c = 0; c < w; c++)
{
int src = r * wb_src + c * 3;
int dst = r * wb_dst + c * 2;
uint16_t blu = (uint16_t)(source[src + 0] * 31.f / 255.f);
uint16_t grn = (uint16_t)(source[src + 1] * 63.f / 255.f);
uint16_t red = (uint16_t)(source[src + 2] * 31.f / 255.f);
uint16_t res = (red) | (grn << 5) | (blu << 11);
memcpy(&dest[dst], &res, 2);
}
}
//prepare header files for 16-bit file
BITMAPINFOHEADER bi = { sizeof(bi), w, h, 1, 16, BI_BITFIELDS };
BITMAPFILEHEADER bf = { (WORD)'MB', 54 + 12 + wb_dst * h, 0, 0, 54 };
std::ofstream of("16bit.bmp", std::ios::binary);
if(of)
{
//add file header
of.write((char*)&bf, sizeof(bf));
of.write((char*)&bi, sizeof(bi));
//color table
COLORREF c1 = 31;
COLORREF c2 = 63 << 5;
COLORREF c3 = 31 << 11;
of.write((char*)&c1, 4);
of.write((char*)&c2, 4);
of.write((char*)&c3, 4);
//add pixels
of.write((char*)&dest[0], dest.size());
}
DeleteObject(hbitmap);
return 0;
}
::operator. Adjust your tags accordingly.bitmap? You're not passing it into the function. Also what type ism_FrameBuffer?