I am working on reading BMP images on a USB and displaying them on a SSD1963 TFT. The below code will read the bmp header, then parse the image data to display on a TFT (BMP565 format). The issue I am having is the code works if the image is 100px X 100px. But it the height and width are not the same, it doesn't display correctly. e.g. the image is not recognizable, but the height and width are correct. From reading online, I need to calculate the number of pixels in each row, which I do, but I suspect how I am not iterating over the rows correctly.
void display_bmp(int x1, int y1, char *bitmap){ uint32_t bmpWidth = 0; uint32_t bmpHeight = 0; uint16_t bmpImageoffset; uint16_t rowSize; uint8_t header_buff[60]; uint16_t position = 0; uint8_t numberOfPixels = 0; uint32_t commpression = 0; uint32_t imageSize = 0; unsigned int byte_read; uint16_t bmpSig; volatile uint8_t lun = LUN_ID_USB; /* Mount drive */ memset(&fs, 0, sizeof(FATFS)); FRESULT res = f_mount(lun, &fs); if (FR_INVALID_DRIVE == res) { printf("Mount Failed!\n\r"); return; } printf("loading %s\n\r", (char *)bitmap); res = f_open(&file_object,(char *)bitmap, FA_OPEN_EXISTING | FA_READ); if (res == FR_NOT_READY || res != FR_OK) { /* LUN not ready or LUN test error */ printf("File open failed!\n\r"); f_close(&file_object); return; } // Read the bmp header res = f_read(&file_object, header_buff, sizeof header_buff, &byte_read); if(res != FR_OK){ print_fs_result(res); return; } bmpSig = (header_buff[1] << 8) | header_buff[0]; printf("Signature:\t0x%X\n", bmpSig); if(bmpSig != 0x4D42){ return; // not a bmp } bmpImageoffset = header_buff[7] * 256 + header_buff[6]; bmpHeight = (header_buff[25] << 24) | (header_buff[24] << 16) | (header_buff[23] << 8) | header_buff[22]; bmpWidth = (header_buff[15] << 24) | (header_buff[16] << 16) | (header_buff[17] << 8) | header_buff[18]; position = header_buff[10]; // starting point in file numberOfPixels = header_buff[29] * 256 + header_buff[28]; commpression = (header_buff[30] << 24) | (header_buff[31] << 16) | (header_buff[32] << 8) | header_buff[33]; imageSize = (header_buff[37] << 24) | (header_buff[36] << 16) | (header_buff[35] << 8) | header_buff[34]; if(tft_conf.orient == LANDSCAPE){ swap(uint32_t, bmpWidth, bmpHeight); } rowSize = ((numberOfPixels * bmpWidth + 31) /32 ) * 4; printf("Offset:\t%d\n", bmpImageoffset); printf("Height:\t%ld\n", bmpHeight); printf("Width:\t\t%ld\n", bmpWidth); printf("Row Size:\t%d\n", rowSize); printf("Start Index:\t%d\n", position); printf("# of Pixels:\t%d\n", numberOfPixels); printf("Compression:\t%ld\n", commpression); printf("Image Size:\t%ld\n", imageSize); // end header read sam_clearCs(); sam_setXY(x1, y1,(bmpWidth + x1) -1, (bmpHeight + y1)-1); uint8_t row_buff[rowSize]; // only read 1 row at a time res = f_lseek(&file_object, position); // start at beginning of image data for(uint32_t row = 0; row < bmpHeight; row++){ // read 1 row at a time res = f_read(&file_object, row_buff, sizeof row_buff, &byte_read); // read 1 row if(res != FR_OK){ print_fs_result(res); return; } position = position + rowSize; // calculate next position on disk to read res = f_lseek(&file_object, position); // set next position if(res != FR_OK){ print_fs_result(res); return; } // read the buffer and send to TFT for (int x = rowSize; x > 0 ; x -= 3) { uint16_t colorbyte = sam_color565(row_buff[x + 2], row_buff[x + 1], row_buff[x]); sam_writeData(colorbyte >> 8, colorbyte & 0xFF); } } // end while sam_setCs(); sam_clrXY(); f_close(&file_object); }