From 96f6e5584a9635a268bd6e94f70cddd198d06a4d Mon Sep 17 00:00:00 2001 From: Thomas Ballmann Date: Sat, 28 Mar 2020 10:45:10 +0100 Subject: [PATCH] refactoring to support multiple image decoder #7 --- include/image.h | 5 ++++ platformio.ini | 1 + src/image.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ src/imagePNG.cpp | 65 +++++----------------------------------- 4 files changed, 90 insertions(+), 58 deletions(-) diff --git a/include/image.h b/include/image.h index 6e88919..8253c0b 100644 --- a/include/image.h +++ b/include/image.h @@ -19,4 +19,9 @@ void ImageNew(int x, int y, int w, int h, bool dithering); void ImageWriteBuffer(uint8_t buff[], size_t c); void ImageFlushBuffer(); +void ImageProcessPixel(uint32_t x, uint32_t y, uint8_t rgba[4]); + +uint16_t drawRGB24toRGB565(uint8_t r, uint8_t g, uint8_t b); +uint32_t drawRGB565toBGRA32(uint16_t color); + #endif /* IMAGE_H */ \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 86f8b7a..5fe819e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -31,6 +31,7 @@ lib_deps = ESP Async WebServer@~1.2.3 ArduinoJson@~6.14.1 https://github.com/kikuchan/pngle.git + TJpg_Decoder@~0.0.3 # Semantic Versioning Rules # http://docs.platformio.org/page/userguide/lib/cmd_install.html#description diff --git a/src/image.cpp b/src/image.cpp index c6f0992..46f56ff 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -2,8 +2,13 @@ #include "imageWBMP.h" #include "imagePNG.h" #include "imageJPEG.h" +#include "display.h" structImageProcess ImageProcess; +// TODO use dynamic display width +static constexpr int MAX_WIDTH = 640; +static int16_t curRowDelta[MAX_WIDTH + 1]; +static int16_t nextRowDelta[MAX_WIDTH + 1]; void setupImage() { @@ -20,6 +25,9 @@ void ImageNew(int x, int y, int w, int h, bool dithering) ImageProcess.w = w; ImageProcess.h = h; ImageProcess.dithering = dithering; + + memset(curRowDelta, 0, sizeof(curRowDelta)); + memset(nextRowDelta, 0, sizeof(nextRowDelta)); } void ImageWriteBuffer(uint8_t buff[], size_t c) @@ -105,4 +113,73 @@ void ImageFlushBuffer() ImageProcess.w = 0; ImageProcess.h = 0; ImageProcess.dithering = false; +} + +void ImageProcessPixel(uint32_t x, uint32_t y, uint8_t rgba[4]) +{ + //uint32_t b = color & 0x001F; // 5 bits blue + //uint32_t g = color & 0x07E0; // 6 bits green + //uint32_t r = color & 0xF800; // 5 bits red + uint8_t r = rgba[0]; // 0 - 255 + uint8_t g = rgba[1]; // 0 - 255 + uint8_t b = rgba[2]; // 0 - 255 + + int16_t gray = round(r * 0.3 + g * 0.59 + b * 0.11); + int16_t blackOrWhite; + + // Add errors to color if there are + if (ImageProcess.dithering) + { + gray += curRowDelta[x]; + } + + if (gray <= 127) + { + blackOrWhite = 0; + } + else + { + blackOrWhite = 255; + } + + if (ImageProcess.dithering) + { + int16_t oldPixel = gray; + int16_t newPixel = blackOrWhite; + + int err = oldPixel - newPixel; + + if (x > 0) + { + nextRowDelta[x - 1] += err * 3 / 16; + } + nextRowDelta[x] += err * 5 / 16; + nextRowDelta[x + 1] += err * 1 / 16; + curRowDelta[x + 1] += err * 7 / 16; + + if (x == 0 && y > 0) + { + // new line + memcpy(curRowDelta, nextRowDelta, sizeof(curRowDelta)); + memset(nextRowDelta, 0, sizeof(nextRowDelta)); + } + } + + displayWritePixel(ImageProcess.x + x, ImageProcess.y + y, blackOrWhite); +} + +uint16_t drawRGB24toRGB565(uint8_t r, uint8_t g, uint8_t b) +{ + return ((r / 8) << 11) | ((g / 4) << 5) | (b / 8); +} + +uint32_t drawRGB565toBGRA32(uint16_t color) +{ + uint32_t bits = (uint32_t)color; + uint32_t blue = bits & 0x001F; // 5 bits blue + uint32_t green = bits & 0x07E0; // 6 bits green + uint32_t red = bits & 0xF800; // 5 bits red + + // Return shifted bits with alpha set to 0xFF + return (red << 8) | (green << 5) | (blue << 3) | 0xFF000000; } \ No newline at end of file diff --git a/src/imagePNG.cpp b/src/imagePNG.cpp index 7d0242f..0e865f8 100644 --- a/src/imagePNG.cpp +++ b/src/imagePNG.cpp @@ -5,12 +5,14 @@ pngle_t *pngle; -// TODO use dynamic display width -static constexpr int MAX_WIDTH = 640; -static int16_t curRowDelta[MAX_WIDTH + 1]; -static int16_t nextRowDelta[MAX_WIDTH + 1]; +void on_draw(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4]) +{ + uint8_t r = rgba[0]; // 0 - 255 + uint8_t g = rgba[1]; // 0 - 255 + uint8_t b = rgba[2]; // 0 - 255 -void on_draw(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4]); + ImageProcessPixel(x, y, rgba); +} void setupImagePNG() { @@ -26,9 +28,6 @@ void pngOpenFramebuffer() { displayOpen(); pngle_reset(pngle); - - memset(curRowDelta, 0, sizeof(curRowDelta)); - memset(nextRowDelta, 0, sizeof(nextRowDelta)); } void pngWriteFramebuffer(int offset, uint8_t bitmap[], int c) @@ -44,54 +43,4 @@ void pngFlushFramebuffer() { Serial.println("pngFlushFramebuffer"); pngle_reset(pngle); -} - -void on_draw(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4]) -{ - uint8_t r = rgba[0]; // 0 - 255 - uint8_t g = rgba[1]; // 0 - 255 - uint8_t b = rgba[2]; // 0 - 255 - - int16_t gray = round(r * 0.3 + g * 0.59 + b * 0.11); - int16_t blackOrWhite; - - // Add errors to color if there are - if (ImageProcess.dithering) - { - gray += curRowDelta[x]; - } - - if (gray <= 127) - { - blackOrWhite = 0; - } - else - { - blackOrWhite = 255; - } - - if (ImageProcess.dithering) - { - int16_t oldPixel = gray; - int16_t newPixel = blackOrWhite; - - int err = oldPixel - newPixel; - - if (x > 0) - { - nextRowDelta[x - 1] += err * 3 / 16; - } - nextRowDelta[x] += err * 5 / 16; - nextRowDelta[x + 1] += err * 1 / 16; - curRowDelta[x + 1] += err * 7 / 16; - - if (x == 0 && y > 0) - { - // new line - memcpy(curRowDelta, nextRowDelta, sizeof(curRowDelta)); - memset(nextRowDelta, 0, sizeof(nextRowDelta)); - } - } - - displayWritePixel(ImageProcess.x + x, ImageProcess.y + y, blackOrWhite); } \ No newline at end of file