From 48f08171f3d17a841357fac73f9f5f07e66d6bcd Mon Sep 17 00:00:00 2001 From: Thorinair Date: Mon, 27 Jul 2020 15:42:41 +0200 Subject: [PATCH] Add support for 4b and 8b bitmaps over web. --- Inkplate.cpp | 106 ++++++++++++++++-- Inkplate.h | 2 + .../10-Inkplate_Download_And_Show.ino | 3 +- 3 files changed, 97 insertions(+), 14 deletions(-) diff --git a/Inkplate.cpp b/Inkplate.cpp index e8edecd..8fad2f5 100644 --- a/Inkplate.cpp +++ b/Inkplate.cpp @@ -363,9 +363,9 @@ int Inkplate::drawBitmapFromSD(char* fileName, int x, int y, bool invert) { int Inkplate::drawBitmapFromWeb(WiFiClient* s, int x, int y, int len, bool invert) { struct bitmapHeader bmpHeader; readBmpHeaderWeb(s, &bmpHeader); - if (bmpHeader.signature != 0x4D42 || bmpHeader.compression != 0 || !(bmpHeader.color == 1 || bmpHeader.color == 24)) return 0; + if (bmpHeader.signature != 0x4D42 || bmpHeader.compression != 0 || !(bmpHeader.color == 1 || bmpHeader.color == 4 || bmpHeader.color == 8 || bmpHeader.color == 24)) return 0; - if ((bmpHeader.color == 24 || bmpHeader.color == 32) && getDisplayMode() != INKPLATE_3BIT) { + if ((bmpHeader.color == 4 || bmpHeader.color == 8 || bmpHeader.color == 24 || bmpHeader.color == 32) && getDisplayMode() != INKPLATE_3BIT) { selectDisplayMode(INKPLATE_3BIT); } @@ -374,6 +374,8 @@ int Inkplate::drawBitmapFromWeb(WiFiClient* s, int x, int y, int len, bool inver } if (bmpHeader.color == 1) drawMonochromeBitmapWeb(s, bmpHeader, x, y, len, invert); + if (bmpHeader.color == 4) drawGrayscaleBitmap4Web(s, bmpHeader, x, y, len, invert); + if (bmpHeader.color == 8) drawGrayscaleBitmap8Web(s, bmpHeader, x, y, len, invert); if (bmpHeader.color == 24) drawGrayscaleBitmap24Web(s, bmpHeader, x, y, len, invert); return 1; @@ -931,11 +933,7 @@ int Inkplate::drawMonochromeBitmapWeb(WiFiClient *s, struct bitmapHeader bmpHead int i, j, k = bmpHeader.startRAW - 34; for (j = 0; j < h; j++) { for (i = 0; i < w; i++) { - uint8_t a = buf[k++]; - uint8_t b = buf[k++]; - uint8_t c = buf[k++]; - uint8_t d = buf[k++]; - uint32_t pixelRow = a << 24 | b << 16 | c << 8 | d; + uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++]; if (invert) pixelRow = ~pixelRow; for (int n = 0; n < 32; n++) { @@ -943,11 +941,7 @@ int Inkplate::drawMonochromeBitmapWeb(WiFiClient *s, struct bitmapHeader bmpHead } } if (paddingBits) { - uint8_t a = buf[k++]; - uint8_t b = buf[k++]; - uint8_t c = buf[k++]; - uint8_t d = buf[k++]; - uint32_t pixelRow = a << 24 | b << 16 | c << 8 | d; + uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++]; if (invert) pixelRow = ~pixelRow; for (int n = 0; n < paddingBits; n++) { @@ -961,6 +955,94 @@ int Inkplate::drawMonochromeBitmapWeb(WiFiClient *s, struct bitmapHeader bmpHead return 1; } +int Inkplate::drawGrayscaleBitmap4Web(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert) { + int w = bmpHeader.width; + int h = bmpHeader.height; + char paddingBits = w % 8; + int total = len - 34; + w /= 8; + + uint8_t* buf = (uint8_t*) ps_malloc(total); + if (buf == NULL) + return 0; + + int pnt = 0; + while (pnt < total) { + int toread = s->available(); + if (toread > 0) { + int read = s->read(buf+pnt, toread); + if (read > 0) + pnt += read; + } + } + + int i, j, k = bmpHeader.startRAW - 34; + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) { + uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++]; + if (invert) + pixelRow = ~pixelRow; + for (int n = 0; n < 8; n++) { + drawPixel((i * 8) + n + x, h - 1 - j + y, (pixelRow & (0xFULL << (28 - n*4))) >> (28 - n*4 + 1)); + } + } + if (paddingBits) { + uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++]; + if (invert) + pixelRow = ~pixelRow; + for (int n = 0; n < paddingBits; n++) { + drawPixel((i * 8) + n + x, h - 1 - j + y, ((pixelRow & (0xFULL << (28 - n*4)))) >> (28 - n*4 + 1)); + } + } + } + + free(buf); + + return 1; +} + +int Inkplate::drawGrayscaleBitmap8Web(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert) { + int w = bmpHeader.width; + int h = bmpHeader.height; + char padding = w % 4; + int total = len - 34; + + uint8_t* buf = (uint8_t*) ps_malloc(total); + if (buf == NULL) + return 0; + + int pnt = 0; + while (pnt < total) { + int toread = s->available(); + if (toread > 0) { + int read = s->read(buf+pnt, toread); + if (read > 0) + pnt += read; + } + } + + int i, j, k = bmpHeader.startRAW - 34; + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) { + uint8_t px = 0; + if (invert) + px = 255-buf[k++]; + else + px = buf[k++]; + drawPixel(i + x, h - 1 - j + y, px>>5); + } + if (padding) { + for (int p = 0; p < 4-padding; p++) { + k++; + } + } + } + + free(buf); + + return 1; +} + int Inkplate::drawGrayscaleBitmap24Web(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert) { int w = bmpHeader.width; int h = bmpHeader.height; diff --git a/Inkplate.h b/Inkplate.h index 82c25c9..74e13a4 100644 --- a/Inkplate.h +++ b/Inkplate.h @@ -171,6 +171,8 @@ class Inkplate : public Adafruit_GFX { int drawMonochromeBitmapSd(SdFile *f, struct bitmapHeader bmpHeader, int x, int y, bool invert); int drawGrayscaleBitmap24Sd(SdFile *f, struct bitmapHeader bmpHeader, int x, int y, bool invert); int drawMonochromeBitmapWeb(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert); + int drawGrayscaleBitmap4Web(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert); + int drawGrayscaleBitmap8Web(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert); int drawGrayscaleBitmap24Web(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert); void precalculateGamma(uint8_t* c, float gamma); }; diff --git a/examples/2. Advanced Inkplate Features/10-Inkplate_Download_And_Show/10-Inkplate_Download_And_Show.ino b/examples/2. Advanced Inkplate Features/10-Inkplate_Download_And_Show/10-Inkplate_Download_And_Show.ino index df58bc5..97ad153 100644 --- a/examples/2. Advanced Inkplate Features/10-Inkplate_Download_And_Show/10-Inkplate_Download_And_Show.ino +++ b/examples/2. Advanced Inkplate Features/10-Inkplate_Download_And_Show/10-Inkplate_Download_And_Show.ino @@ -24,7 +24,6 @@ #include "HTTPClient.h" //Include library for HTTPClient #include "WiFi.h" //Include library for WiFi Inkplate display(INKPLATE_1BIT); //Create an object on Inkplate library and also set library into 1 Bit mode (Monochrome) -SdFile file; //Create SdFile object used for accessing files on SD card const char* ssid = "YourWiFiSSID"; //Your WiFi SSID const char* password = "YourPass"; //Your WiFi password @@ -68,7 +67,7 @@ void setup() { //Set parameters to speed up the download process. http.getStream().setNoDelay(true); http.getStream().setTimeout(1); - + //Photo taken by: Roberto Fernandez http.begin("https://varipass.org/neowise.bmp");