-
Notifications
You must be signed in to change notification settings - Fork 47
Description
Describe the bug
Having two images. Image A and image B.
Decode image A, it will be perfect. Decode image B, then B will have a red vertical bar all over its extension.
Invert the order, B then A, is all fine. Its seems to be some issue in image A that leaks trough the decompressor.
To Reproduce
Steps to reproduce the behavior:
- Get an esp32s3 with an SD card (Might be still happening between other esps).
Use a code like this. Happens with any code, just providing the one i used)
#include <Arduino.h>
#include <SD.h>
#include <PNGdec.h>
#include "SPI.h"
#include <string>
#define SPI_CS 38
#define SPI_MOSI 14
#define SPI_MISO 47
#define SPI_SCK 21
#define SPI_MAX_CLOCK (80 * 1000 * 1000)
#define PANEL_WIDTH 64
#define PANEL_HEIGHT 32
#define FILE_PIXEL_COUNT PANEL_WIDTH * PANEL_HEIGHT
#define FILE_SIZE_BULK_SIZE ( FILE_PIXEL_COUNT * sizeof(uint16_t) )
File getFile(const char *name){
File myFile = SD.open(name);
return myFile;
}
uint16_t* tmpBuffer;
File pngDecFile;
PNG png;
void * myOpen(const char *filename, int32_t *size) {
pngDecFile = SD.open(filename);
*size = pngDecFile.size();
return &pngDecFile;
}
void myClose(void *handle) {
if (pngDecFile) pngDecFile.close();
}
int32_t myRead(PNGFILE *handle, uint8_t *buffer, int32_t length) {
if (!pngDecFile) return 0;
return pngDecFile.read(buffer, length);
}
int32_t mySeek(PNGFILE *handle, int32_t position) {
if (!pngDecFile) return 0;
return pngDecFile.seek(position);
}
// Function to draw pixels to the display
int PNGDraw(PNGDRAW *pDraw) {
static uint16_t raw[128];
png.getLineAsRGB565(pDraw, raw, PNG_RGB565_LITTLE_ENDIAN, 0xffffffff);
memcpy(tmpBuffer + (pDraw->y *pDraw->iWidth), raw, pDraw->iWidth * sizeof(uint16_t));
return 1;
}
uint16_t *DecodePNGForBuffer(const char *name, int& rcError){
auto fp = getFile(name);
if (!fp){
rcError = 998;
return nullptr;
}
fp.close();
rcError = png.open(name, myOpen, myClose, myRead, mySeek, PNGDraw);
if (rcError != PNG_SUCCESS) {
return nullptr;
}
Serial.printf("File is size %d %d\n", png.getWidth(), png.getHeight());
if (png.getWidth() != PANEL_WIDTH && png.getHeight() != PANEL_HEIGHT){
Serial.printf("Mismatched image size, expected %d %d but got %d %d", PANEL_WIDTH, PANEL_HEIGHT, png.getWidth(), png.getHeight());
png.close();
rcError = 999;
return nullptr;
}
tmpBuffer = (uint16_t*)ps_malloc(FILE_SIZE_BULK_SIZE );
png.decode(NULL, 0);
png.close();
int x = 0;
int y = 0;
Serial.printf("[00]=");
for (int i=0;i<FILE_SIZE_BULK_SIZE;i++){
uint16_t color = tmpBuffer[i];
Serial.printf("%05d,", color);
x++;
if (x > PANEL_WIDTH){
x = 0;
y++;
Serial.printf("\n[%02d]=", y);
}
}
Serial.printf("\n\n\nFinished file: %s!\n", name);
return tmpBuffer;
}
void setup() {
Serial.begin(115200);
SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI, SPI_CS);
SPI.setFrequency(SPI_MAX_CLOCK);
Serial.println("Initializing SD card...");
if(!SD.begin(SPI_CS, SPI, SPI_MAX_CLOCK, "/sd", 10)){
return;
}
Serial.println("SD OK!");
int error;
uint16_t *buffA = DecodePNGForBuffer("/imagea.png", error);
uint16_t *buffB = DecodePNGForBuffer("/imageb.png", error);
}
void loop() {}Flash it, and load those two images in to the SD card:
https://dogurai.com/imagea.png
https://dogurai.com/imageb.png
Or here as zip:
Checking the console will output the image pixels, those are 64x32 pixel images.
You will see this o the first lines of the imageb
Finished file: /expressions/imagec.png!
File is size 64 32
[00]=00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,63488,00000,
That 63488 was'nt supposed to be there, it happens on the same row of every single line. Sometimes taking 4 rows, sometimes taking one.
Expected behavior
No red line visible
Image you're having trouble with
https://dogurai.com/imagea.png
https://dogurai.com/imageb.png
Additional context
I hosted the images in a site i own so you can download without any tool compressing it in any way. I know its a encoding related issue, because loading the image using mspaint, editing any pixel and saving again solve the issue.
The original image as edited using paintnet, but i saw this happening with some images done by phone.
