refactoring to support multiple image decoder #7

pull/1/head
Thomas Ballmann 4 years ago
parent cf9436f0e8
commit 96f6e5584a

@ -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 */

@ -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

@ -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;
}

@ -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);
}
Loading…
Cancel
Save