Opening 32bit BMP parts

Hi everyone,

I've created the following function from an example, to show parts of bmp files on a screen. It has the following parameters:
*nm : filename
x : X starting coordinate on screen for the bmp
y : Y starting coordinate on screen for the bmp
startX : X starting coordinate on the bmp
startY : Y starting coordinate on the bmp
sizeX : Length of the bmp piece showed
sizeY : Height of the bmp piece showed

It works, but only if the BMP is 8 bit and if it's upside down. I would like to change that to 32 bit and for normal pictures(so I don't have to flip all my pictures).

I'm using the following libraries:
#include <MCUFRIEND_kbv.h>
#include <Adafruit_GFX.h>

uint8_t showBMP( char *nm, int x, int y, int startX, int startY, int sizeX, int sizeY ) {
File bmpFile;
int bmpWidth, bmpHeight; // W+H in pixels
uint8_t bmpDepth; // Bit depth (currently must be 24, 16, 8, 4, 1)
uint32_t bmpImageoffset; // Start of image data in file
uint32_t rowSize; // Not always = bmpWidth; may have padding
uint8_t sdbuffer[3 * BUFFPIXEL]; // pixel in buffer (R+G+B per pixel)
uint16_t lcdbuffer[(1 << PALETTEDEPTH) + BUFFPIXEL], *palette = NULL;
int row, col, lcdbufsiz = (1 << PALETTEDEPTH) + BUFFPIXEL, buffidx;
uint32_t pos; // seek position
boolean is565 = false; //

uint16_t bmpID;
uint16_t n; // blocks read
uint8_t ret;

if ( ( x >= tft.width() ) || ( y >= tft.height() ) )
return 1; // off screen

bmpFile = SD.open(nm); // Parse BMP header
bmpID = read16(bmpFile); // BMP signature
(void) read32(bmpFile); // Read & ignore file size
(void) read32(bmpFile); // Read & ignore creator bytes
bmpImageoffset = read32(bmpFile); // Start of image data
(void) read32(bmpFile); // Read & ignore DIB header size
bmpWidth = read32(bmpFile);
bmpHeight = read32(bmpFile);
n = read16(bmpFile); // # planes -- must be '1'
bmpDepth = read16(bmpFile); // bits per pixel
pos = read32(bmpFile); // format
if ( bmpID != 0x4D42 ) ret = 2; // bad ID
else if ( n != 1 ) ret = 3; // too many planes
else if ( pos != 0 && pos != 3 ) ret = 4; // format: 0 = uncompressed, 3 = 565
else if ( bmpDepth < 16 && bmpDepth > PALETTEDEPTH ) ret = 5; // palette
else {
bool first = true;
is565 = (pos == 3); // ?already in 16-bit format
// BMP rows are padded (if needed) to 4-byte boundary
rowSize = ( bmpWidth * bmpDepth / 8 + 3 ) & ~3;
if ( bmpHeight < 0 ) { // If negative, image is in top-down order.
bmpHeight = -bmpHeight;
// flip = false;
}

// Set TFT address window to clipped image bounds
tft.setAddrWindow(x, y, x + sizeX - 1, y + sizeY - 1);
for ( row = startY; row < startY+sizeY; row++ ) { // For each scanline...
uint8_t r, g, b, *sdptr;
int lcdidx, lcdleft;
pos = bmpImageoffset + row * rowSize +2 * startX;
bmpFile.seek(pos);//Adjust X position TOP DOWN PICTURES ONLY!!!
buffidx = sizeof(sdbuffer); // Force buffer reload

for ( col = 0; col < sizeX; ) { //pixels in row
lcdleft = sizeX - col;
if ( lcdleft > lcdbufsiz ) lcdleft = lcdbufsiz;
for (lcdidx = 0; lcdidx < lcdleft; lcdidx++) { // buffer at a time
uint16_t color;
// Time to read more pixel data?
if ( buffidx >= sizeof(sdbuffer) ) { // Indeed
bmpFile.read(sdbuffer, sizeof(sdbuffer));
buffidx = 0; // Set index to beginning
r = 0;
}
switch (bmpDepth) { // Convert pixel from BMP to TFT format
case 24:
b = sdbuffer[buffidx++];
g = sdbuffer[buffidx++];
r = sdbuffer[buffidx++];
color = tft.color565(r, g, b);
break;
case 16:
b = sdbuffer[buffidx++];
r = sdbuffer[buffidx++];
if ( is565 ) color = (r << 😎 | (b); else color = (r << 9) | ((b & 0xE0) << 1) | (b & 0x1F);
break;
}
lcdbuffer[lcdidx] = color;
}
tft.pushColors(lcdbuffer, lcdidx, first);
first = false;
col += lcdidx;
} // end cols
} // end rows
tft.setAddrWindow(0, 0, tft.width() - 1, tft.height() - 1); //restore full screen
ret = 0; // good render
}
bmpFile.close();
return (ret);
}

I'm not quite familiar how the bmp is built up, any help in that area would also be appreciated. Could you please help me? Thanks in advance!

BMP image file format is well documented in many places on the web.

Start here: BMP file format - Wikipedia

Not sure what you mean by "upside down". The BMP standard is "bottom up", meaning the first pixels in the file are the bottom left corner of the image (Y indexing of most displays starts at top left). The BMP header has flags for alternative Y indexing.

Why? The Adafruit_GFX library has several commands for displaying BMP images like drawBitmap, drawXBitmap, drawGrayscaleBitmap and drawRGBBitmap.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.