Advertisement
LeventeDaradici

support_functions.h

May 11th, 2023
1,263
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.38 KB | Source Code | 0 0
  1. #include <math.h>
  2.  
  3. #include "pngle.h"
  4.  
  5. #define LINE_BUF_SIZE 64  // pixel = 524, 16 = 406, 32 = 386, 64 = 375, 128 = 368, 240 = 367, no draw = 324 (51ms v 200ms)
  6. int16_t px = 0, sx = 0;
  7. int16_t py = 0, sy = 0;
  8. uint8_t pc = 0;
  9. uint16_t lbuf[LINE_BUF_SIZE];
  10.  
  11.  int16_t png_dx = 0, png_dy = 0;
  12.  
  13. // Define corner position
  14. void setPngPosition(int16_t x, int16_t y)
  15. {
  16.   png_dx = x;
  17.   png_dy = y;
  18. }
  19.  
  20. // Draw pixel - called by pngle
  21. void pngle_on_draw(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4])
  22. {
  23.   uint16_t color = (rgba[0] << 8 & 0xf800) | (rgba[1] << 3 & 0x07e0) | (rgba[2] >> 3 & 0x001f);
  24.  
  25. #if !defined(USE_ADAFRUIT_GFX) && defined(USE_LINE_BUFFER)
  26.   color = (color << 8) | (color >> 8);
  27. #endif
  28.  
  29.   if (rgba[3] > 127) { // Transparency threshold (no blending yet...)
  30.  
  31.   #ifdef USE_LINE_BUFFER // This must handle skipped pixels in transparent PNGs
  32.     if ( pc >= LINE_BUF_SIZE) {
  33.       #ifdef USE_ADAFRUIT_GFX
  34.         tft.drawRGBBitmap(png_dx + sx, png_dy + sy, lbuf, LINE_BUF_SIZE, 1);
  35.       #else
  36.         tft.pushImage(png_dx + sx, png_dy + sy, LINE_BUF_SIZE, 1, lbuf);
  37.       #endif
  38.       px = x; sx = x; sy = y; pc = 0;
  39.     }
  40.  
  41.     if ( (x == px) && (sy == y) && (pc < LINE_BUF_SIZE) ) {px++; lbuf[pc++] = color;}
  42.     else {
  43.       #ifdef USE_ADAFRUIT_GFX
  44.         tft.drawRGBBitmap(png_dx + sx, png_dy + sy, lbuf, pc, 1);
  45.       #else
  46.         tft.pushImage(png_dx + sx, png_dy + sy, pc, 1, lbuf);
  47.       #endif
  48.       px = x; sx = x; sy = y; pc = 0;
  49.       px++; lbuf[pc++] = color;
  50.     }
  51.   #else
  52.     tft.drawPixel(x, y, color);
  53.   #endif
  54.   }
  55. }
  56.  
  57. // Render from SPIFFS or SD
  58. void load_file(fs::FS &fs, const char *path)
  59. {
  60.   fs::File file = fs.open(path);
  61.   if (!file) {
  62.     Serial.println("Failed to open file for reading");
  63.     return ;
  64.   }
  65.  
  66.   pngle_t *pngle = pngle_new();
  67.   pngle_set_draw_callback(pngle, pngle_on_draw);
  68.  
  69.   // Feed data to pngle
  70.   uint8_t buf[1024];
  71.  
  72.   int remain = 0;
  73.   int len;
  74.   #if !defined(USE_ADAFRUIT_GFX) && !defined(USE_LINE_BUFFER)
  75.    tft.startWrite(); // Crashes Adafruit_GFX
  76.   #endif
  77.  
  78.   while ((len = file.read(buf + remain, sizeof(buf) - remain)) > 0) {
  79.     int fed = pngle_feed(pngle, buf, remain + len);
  80.     if (fed < 0) {
  81.       Serial.printf("ERROR: %s\n", pngle_error(pngle));
  82.       break;
  83.     }
  84.  
  85.     remain = remain + len - fed;
  86.     if (remain > 0) memmove(buf, buf + fed, remain);
  87.   }
  88. #ifdef USE_LINE_BUFFER
  89.    // Draw any remaining pixels - had no warning that image has ended...
  90.   if (pc) {
  91.   #ifdef USE_ADAFRUIT_GFX
  92.     tft.drawRGBBitmap(png_dx + sx, png_dy + sy, lbuf, pc, 1);
  93.   #else
  94.     tft.pushImage(png_dx + sx, png_dy + sy, pc, 1, lbuf);
  95.   #endif
  96.     pc = 0;
  97.   }
  98. #endif
  99.   #if !defined(USE_ADAFRUIT_GFX) && !defined(USE_LINE_BUFFER)
  100.     tft.endWrite();
  101.   #endif
  102.   pngle_destroy(pngle);
  103.   file.close();
  104. }
  105.  
  106.  
  107. void load_png(const char *url)
  108. {
  109.   HTTPClient http;
  110.  
  111.   http.begin(url);
  112.  
  113.   int httpCode = http.GET();
  114.   if (httpCode != HTTP_CODE_OK) {
  115.     Serial.printf("HTTP ERROR: %d\n", httpCode);
  116.     http.end();
  117.     return ;
  118.   }
  119.   int total = http.getSize();
  120.  
  121.   WiFiClient *stream = http.getStreamPtr();
  122.  
  123.   pngle_t *pngle = pngle_new();
  124.   pngle_set_draw_callback(pngle, pngle_on_draw);
  125.  
  126.   uint8_t buf[1024];
  127.   int remain = 0;
  128.   int len;
  129.   uint32_t timeout = 0;
  130.  
  131.   #if !defined(USE_ADAFRUIT_GFX) && !defined(USE_LINE_BUFFER)
  132.     tft.startWrite(); // Crashes Adafruit_GFX
  133.   #endif
  134.   while (http.connected() && (total > 0 || total == -1)) {
  135.     size_t size = stream->available();
  136.  
  137.     if (timeout > 500) break;
  138.     if (!size) { delay(2); timeout++;  continue; }
  139.     if (size > sizeof(buf) - remain) size = sizeof(buf) - remain;
  140.  
  141.     if ((len = stream->readBytes(buf + remain, size)) > 0) {
  142.       int fed = pngle_feed(pngle, buf, remain + len);
  143.       if (fed < 0) {
  144.         Serial.printf("ERROR: %s\n", pngle_error(pngle));
  145.         break;
  146.       }
  147.       remain = remain + len - fed;
  148.       if (remain > 0) memmove(buf, buf + fed, remain);
  149.       total -= len;
  150.     }
  151.   }
  152. #ifdef USE_LINE_BUFFER
  153.   // Draw any remaining pixels
  154.   if (pc) {
  155.   #ifdef USE_ADAFRUIT_GFX
  156.     tft.drawRGBBitmap(png_dx + sx, png_dy + sy, lbuf, pc, 1);
  157.   #else
  158.     tft.pushImage(png_dx + sx, png_dy + sy, pc, 1, lbuf);
  159.   #endif
  160.     pc = 0;
  161.   }
  162. #endif
  163.   #if !defined(USE_ADAFRUIT_GFX) && !defined(USE_LINE_BUFFER)
  164.     tft.endWrite();
  165.   #endif
  166.   pngle_destroy(pngle);
  167.   http.end();
  168. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement