From b4c8f249f5518e896018c6823b40eb3f07e1646b Mon Sep 17 00:00:00 2001 From: Thomas Ballmann Date: Thu, 24 Dec 2020 12:18:48 +0100 Subject: [PATCH] #50 handle dynamic display size --- lib/app/app.cpp | 4 ++-- lib/display/display.cpp | 13 ++++++++++++- lib/image/image.cpp | 33 +++++++++++++++++++-------------- lib/image/imageJPEG.cpp | 23 ++++++++++++++++------- 4 files changed, 49 insertions(+), 24 deletions(-) diff --git a/lib/app/app.cpp b/lib/app/app.cpp index 12a1e35..e4ac6a5 100644 --- a/lib/app/app.cpp +++ b/lib/app/app.cpp @@ -117,8 +117,8 @@ void setupApp() doc["device"]["name"] = NVS.getString("device.name"); doc["device"]["hostname"] = WiFi.getHostname(); doc["device"]["bootCycle"] = deviceGetBootCount(); - doc["device"]["screen"]["width"] = 640; - doc["device"]["screen"]["height"] = 384; + doc["device"]["screen"]["width"] = displayGetWidth(); + doc["device"]["screen"]["height"] = displayGetHeight(); doc["device"]["fs"]["total"] = SPIFFS.totalBytes(); doc["device"]["fs"]["used"] = SPIFFS.usedBytes(); diff --git a/lib/display/display.cpp b/lib/display/display.cpp index 3d6e383..9cbc0d6 100644 --- a/lib/display/display.cpp +++ b/lib/display/display.cpp @@ -54,7 +54,18 @@ void displayFlush() display.display(); } -/* +uint16_t displayGetWidth() +{ + return display.width(); +} + +uint16_t displayGetHeight() +{ + return display.height(); +} + + +/* TODO void printSplash() { const char Hello[] = "Hello Paperdash!"; diff --git a/lib/image/image.cpp b/lib/image/image.cpp index b077ec4..b831cb6 100644 --- a/lib/image/image.cpp +++ b/lib/image/image.cpp @@ -4,14 +4,19 @@ #include "display.h" structImageProcess ImageProcess; -// TODO use dynamic display width -constexpr uint16_t MAX_WIDTH = 640; -int16_t curRowDelta[MAX_WIDTH + 1]; -int16_t nextRowDelta[MAX_WIDTH + 1]; + +// dithering +uint16_t ditheringBufferSize; +int16_t *ditheringCurRowDelta; +int16_t *ditheringNextRowDelta; void setupImage() { - setupImagePNG(); + // create buffer for dithering + ditheringBufferSize = displayGetWidth() + 1; + ditheringCurRowDelta = new int16_t[ditheringBufferSize]; + ditheringNextRowDelta = new int16_t[ditheringBufferSize]; + setupImageJPEG(); } @@ -25,8 +30,8 @@ void ImageNew(int x, int y, int w, int h, bool dithering) ImageProcess.h = h; ImageProcess.dithering = dithering; - memset(curRowDelta, 0, sizeof(curRowDelta)); - memset(nextRowDelta, 0, sizeof(nextRowDelta)); + memset(ditheringCurRowDelta, 0, sizeof(ditheringCurRowDelta[0]) * ditheringBufferSize); + memset(ditheringNextRowDelta, 0, sizeof(ditheringNextRowDelta[0]) * ditheringBufferSize); } void ImageWriteBuffer(uint8_t buff[], size_t c) @@ -111,7 +116,7 @@ void ImageProcessPixel(uint16_t x, uint16_t y, uint8_t rgba[4]) // Add errors to color if there are if (ImageProcess.dithering) { - gray += curRowDelta[x]; + gray += ditheringCurRowDelta[x]; } if (gray <= 127) @@ -132,17 +137,17 @@ void ImageProcessPixel(uint16_t x, uint16_t y, uint8_t rgba[4]) if (x > 0) { - nextRowDelta[x - 1] += err * 3 / 16; + ditheringNextRowDelta[x - 1] += err * 3 / 16; } - nextRowDelta[x] += err * 5 / 16; - nextRowDelta[x + 1] += err * 1 / 16; - curRowDelta[x + 1] += err * 7 / 16; + ditheringNextRowDelta[x] += err * 5 / 16; + ditheringNextRowDelta[x + 1] += err * 1 / 16; + ditheringCurRowDelta[x + 1] += err * 7 / 16; if (x == 0 && y > 0) { // new line - memcpy(curRowDelta, nextRowDelta, sizeof(curRowDelta)); - memset(nextRowDelta, 0, sizeof(nextRowDelta)); + memcpy(ditheringCurRowDelta, ditheringNextRowDelta, sizeof(ditheringCurRowDelta[0]) * ditheringBufferSize); + memset(ditheringNextRowDelta, 0, sizeof(ditheringNextRowDelta[0]) * ditheringBufferSize); } } diff --git a/lib/image/imageJPEG.cpp b/lib/image/imageJPEG.cpp index e7ea794..d0600c1 100644 --- a/lib/image/imageJPEG.cpp +++ b/lib/image/imageJPEG.cpp @@ -7,9 +7,11 @@ File tmpFileBuffer; void renderMcuBlock(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *bitmap); -static constexpr uint16_t MAX_WIDTH = 640; // TODO get info from display 800 works :D -static constexpr uint8_t BLOCK_SIZE = 16; // max MCU block size -static uint16_t blockDelta[BLOCK_SIZE * MAX_WIDTH + 1]; +static uint8_t BLOCK_SIZE = 16; // max MCU block size + +int16_t *blockDelta; +uint16_t displayWidth; +uint16_t blockDeltaSize; // TODO uint32_t auf uint16_t ändern um speicher zu sparen // https://os.mbed.com/handbook/C-Data-Types#integer-data-types @@ -21,6 +23,13 @@ static uint16_t blockDelta[BLOCK_SIZE * MAX_WIDTH + 1]; void setupImageJPEG() { Serial.println("setupJPEG"); + + // create working buffer + displayWidth = displayGetWidth(); + blockDeltaSize = BLOCK_SIZE * displayWidth + 1; + blockDelta = new int16_t[blockDeltaSize]; + + Serial.println(sizeof(blockDelta[0]) * blockDeltaSize); } void jpegOpenFramebuffer() @@ -35,7 +44,7 @@ void jpegOpenFramebuffer() Serial.println("Failed to open file for writing"); } - memset(blockDelta, 0, sizeof(blockDelta)); + memset(blockDelta, 0, sizeof(blockDelta[0]) * blockDeltaSize); } void jpegWriteFramebuffer(int offset, uint8_t bitmap[], int c) @@ -189,7 +198,7 @@ void renderMcuBlockPixel(uint16_t x, uint16_t y, uint16_t color) { // collect all mcu blocks for current row uint16_t blockPageY = y - ((y / JpegDec.MCUHeight) * JpegDec.MCUHeight); - blockDelta[(blockPageY * MAX_WIDTH) + x] = color; + blockDelta[(blockPageY * displayWidth) + x] = color; // full mcu row is complete now if (x == JpegDec.width - 1 && (y + 1) % JpegDec.MCUHeight == 0) @@ -204,7 +213,7 @@ void renderMcuBlockPixel(uint16_t x, uint16_t y, uint16_t color) { uint16_t originX = _x; uint16_t originY = originOffsetY + _y; - uint16_t originColor = blockDelta[(_y * MAX_WIDTH) + _x]; + uint16_t originColor = blockDelta[(_y * displayWidth) + _x]; uint8_t r = ((((originColor >> 11) & 0x1F) * 527) + 23) >> 6; uint8_t g = ((((originColor >> 5) & 0x3F) * 259) + 33) >> 6; @@ -216,7 +225,7 @@ void renderMcuBlockPixel(uint16_t x, uint16_t y, uint16_t color) } // clean buffer - memset(blockDelta, 0, sizeof(blockDelta)); + memset(blockDelta, 0, sizeof(blockDelta[0]) * blockDeltaSize); } }