acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

BMP_functions.ino (2354B)

      1 // Bodmer's BMP image rendering function
      2 
      3 void drawBmp(const char *filename, int16_t x, int16_t y) {
      4 
      5   if ((x >= tft.width()) || (y >= tft.height())) return;
      6 
      7   fs::File bmpFS;
      8 
      9   // Open requested file on SD card
     10   bmpFS = SPIFFS.open(filename, "r");
     11 
     12   if (!bmpFS)
     13   {
     14     Serial.print("File not found");
     15     return;
     16   }
     17 
     18   uint32_t seekOffset;
     19   uint16_t w, h, row, col;
     20   uint8_t  r, g, b;
     21 
     22   uint32_t startTime = millis();
     23 
     24   if (read16(bmpFS) == 0x4D42)
     25   {
     26     read32(bmpFS);
     27     read32(bmpFS);
     28     seekOffset = read32(bmpFS);
     29     read32(bmpFS);
     30     w = read32(bmpFS);
     31     h = read32(bmpFS);
     32 
     33     if ((read16(bmpFS) == 1) && (read16(bmpFS) == 24) && (read32(bmpFS) == 0))
     34     {
     35       y += h - 1;
     36 
     37       bool oldSwapBytes = tft.getSwapBytes();
     38       tft.setSwapBytes(true);
     39       bmpFS.seek(seekOffset);
     40 
     41       uint16_t padding = (4 - ((w * 3) & 3)) & 3;
     42       uint8_t lineBuffer[w * 3 + padding];
     43 
     44       for (row = 0; row < h; row++) {
     45         
     46         bmpFS.read(lineBuffer, sizeof(lineBuffer));
     47         uint8_t*  bptr = lineBuffer;
     48         uint16_t* tptr = (uint16_t*)lineBuffer;
     49         // Convert 24 to 16 bit colours
     50         for (uint16_t col = 0; col < w; col++)
     51         {
     52           b = *bptr++;
     53           g = *bptr++;
     54           r = *bptr++;
     55           *tptr++ = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
     56         }
     57 
     58         // Push the pixel row to screen, pushImage will crop the line if needed
     59         // y is decremented as the BMP image is drawn bottom up
     60         tft.pushImage(x, y--, w, 1, (uint16_t*)lineBuffer);
     61       }
     62       tft.setSwapBytes(oldSwapBytes);
     63       Serial.print("Loaded in "); Serial.print(millis() - startTime);
     64       Serial.println(" ms");
     65     }
     66     else Serial.println("BMP format not recognized.");
     67   }
     68   bmpFS.close();
     69 }
     70 
     71 // These read 16- and 32-bit types from the SD card file.
     72 // BMP data is stored little-endian, Arduino is little-endian too.
     73 // May need to reverse subscript order if porting elsewhere.
     74 
     75 uint16_t read16(fs::File &f) {
     76   uint16_t result;
     77   ((uint8_t *)&result)[0] = f.read(); // LSB
     78   ((uint8_t *)&result)[1] = f.read(); // MSB
     79   return result;
     80 }
     81 
     82 uint32_t read32(fs::File &f) {
     83   uint32_t result;
     84   ((uint8_t *)&result)[0] = f.read(); // LSB
     85   ((uint8_t *)&result)[1] = f.read();
     86   ((uint8_t *)&result)[2] = f.read();
     87   ((uint8_t *)&result)[3] = f.read(); // MSB
     88   return result;
     89 }
     90