Open glowlabs opened 6 years ago
// tft.jpgimage(X, Y, scale, file_name, buf, size]
// X & Y can be < 0 !
//=============================================
void TFT_jpg_image(int x, int y, uint8_t scale, char *fname, uint8_t *buf, int size)
So you can use the 5th parameter which is a buffer to send the image to the function
if (fname == NULL) { // image from buffer dev.membuff = buf; dev.bufsize = size; dev.bufptr = 0; }
Hello,
I try to load jpg img from memory too but with no success:
memcpy(disp_buffer, (unsigned char *)img1, sizeof(img1)); TFT_jpg_image(CENTER, CENTER, 0, NULL, disp_buffer, sizeof(disp_buffer));
Do you see what am I doing wrong?
Don't see anything wrong. Maybe try the same image with file name to see if that works first?
Hello,
thanks for you answer! the whole project is great and works fine (also with file name), however I am trying to load other img after an OTA (the device is in another land and there is no way to flash the device manually), so I can't work with file name anymore, that is the reason why I am try to save image directly in memory. I use a jpg to c converter from: https://www.mikrocontroller.net/topic/425390 and get the c array from an image I want to use (by the way the size is much bigger than in .jpg: 704kB instead of 6,5kB for 320*240 pixels!!!). Then I save the img.h ( into the same folder where the main file is) : const unsigned char img[] = {hex converted}; then in main.c :
uint8_t disp_buffer = NULL; ...initialisation... memcpy(disp_buffer, (unsigned char )img, sizeof(img)); TFT_jpg_image(CENTER, CENTER, 0, NULL, disp_buffer, sizeof(disp_buffer));
it compiles but crashes:
Guru Meditation Error: Core 0 panic'ed (StoreProhibited) . Exception was unhandled. Register dump: PC : 0x4000c2e4 PS : 0x00060230 A0 : 0x800d28dc A1 : 0x3ffb75d0 A2 : 0x00000000 A3 : 0x3f403ec4 A4 : 0x0001c200 A5 : 0x00000000 A6 : 0xffffcfcc A7 : 0xffffffff A8 : 0x00000000 A9 : 0x3ffb7590 A10 : 0x00000000 A11 : 0x00000001 A12 : 0x3ffb0854 A13 : 0x3ffb7290 A14 : 0x3ffb7290 A15 : 0x00000004 SAR : 0x0000000e EXCCAUSE: 0x0000001d EXCVADDR: 0x00000000 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0x00001c1f Backtrace: 0x4000c2e4:0x3ffb75d0 0x400d28d9:0x3ffb75e0 0x400d0e86:0x3ffb7670 0x400d28d9: app_main at C:/msys32/home/illy/esp/esp32_wilo/main/code.c:3309 (discriminator 4) 0x400d0e86: main_task at C:/msys32/home/Illy/esp/esp-idf/components/esp32/cpu_start.c:456 CPU halted.
Any idea what I could do?
https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/fatal-errors.html LoadProhibited, StoreProhibited This CPU exception happens when application attempts to read from or write to an invalid memory location. The address which was written/read is found in EXCVADDR register in the register dump. If this address is zero, it usually means that application attempted to dereference a NULL pointer. If this address is close to zero, it usually means that application attempted to access member of a structure, but the pointer to the structure was NULL. If this address is something else (garbage value, not in 0x3fxxxxxx - 0x6xxxxxxx range), it likely means that the pointer used to access the data was either not initialized or was corrupted.
From your stack dump it shows this EXCVADDR: 0x00000000
So there is something wrong with the pointer being used. Maybe because of this line? uint8_t *disp_buffer = NULL;
Sorry I don't have further expertise to help in this... but above information should give some idea on where to look for a solution.
Thanks for the link sukeshak! I changed the code:
int sz=sizeof(img); uint8_t buffer = (uint8_t) malloc(sz); if (buffer == NULL) printf("stop\r\n"); else { printf("start\r\n"); memcpy(buffer, (unsigned char *)img, sz); TFT_jpg_image(CENTER, CENTER, 0, NULL, buffer, sz); } free(buffer);
The CPU doesn't crash anymore :) I try to understand the TFT_jpg_image routine but I don't know how works this function: jd_prepare(&jd, tjd_buf_input, (void *)work, sz_work, &dev); It returns 6 instead of 0. Do you know where I can find that prototype?
Ok I have found it, I am going to study it :)
Well I get JDR_FMT1 as result what means the format is wrong. I have seen in rom/tjpgd.h format is RGB888 3bytes/pixel what I have chosen. Then I have seen another project of Loboris: https://github.com/loboris/ESP32_ePaper_example which alos use images from memory (at least I believe) and took from it the img1.h. The function EPD_jpg_image is almost the same as the TFT_jpg_image. But still doesn't work :( . Have you already loaded an image from memory with success?
Looks like some progress made :)
I am on an international travel so don't have any hardware to try. Will be at least a week plus before I get a chance.
Did you try an image which is part of his samples for testing, to isolate it?
Also probably you can try this since bmp is less complicated
TFT_bmp_image
Well I won't give up with JPG :) ! I have also tried with his sample bot no success. int sz=sizeof(img); printf("size of img:%d\n\r",sz); uint8_t buffer=(uint8_t) malloc(sz); if (buffer) { memcpy(buffer, (unsigned char )img, sz); for (int i=0; i<sz; i++) {printf("%u\n\r",(buffer+i));} TFT_jpg_image(CENTER, CENTER, 0, NULL, buffer, sz); free(buffer); } The buffer is well filled with the JPG converted into RGB888 and fit the size. Then tjd_buf_input function is called but third argument (nd) is always equal to 2 (also reading 2 bytes?), instead of the size of the buffer I think? . I don't understand where comes the 3 argument of the tjd_buf_input function from. It is called with jd_prepare and use the JPGIODEV structure as far I understand. I get always JDR_FMT1 as return.
Using the BMP function is just to further isolate the issue...
Here is the code you need to debug... good luck :) https://github.com/loboris/ESP32_TFT_library/blob/aa21772f54a71887ec08b2e8bbaef9e304009891/components/tft/tft.c#L2376
well that is indeed the code I am trying to debug. I am stucked into the static UINT tjd_buf_input ( JDEC jd, // Decompression object BYTE buff, // Pointer to the read buffer (NULL:skip) UINT nd // Number of bytes to read/skip from input stream ). I don't understand why it only read 2 bytes also why nd is set to 2. Where is it parametrized? it should come from the buf size isn't it? but I have checked that dev.bufsize = size; is well parametrized...
when I take jpg from SPIFFS it shows the right size: static UINT tjd_buf_input ( JDEC jd, // Decompression object BYTE buff, // Pointer to the read buffer (NULL:skip) UINT nd // Number of bytes to read/skip from input stream ) { // Device identifier for the session (5th argument of jd_prepare function) JPGIODEV dev = (JPGIODEV)jd->device; printf("Reading %d bytes from pos %d\n", nd, dev->bufptr); if (!dev->membuff) return 0;
if (dev->bufptr >= (dev->bufsize + 2)) return 0; // end of stream
if ((dev->bufptr + nd) > (dev->bufsize + 2)) nd = (dev->bufsize + 2) - dev->bufptr;
if (buff) { // Read nd bytes from the input strem
memcpy(buff, dev->membuff + dev->bufptr, nd);
dev->bufptr += nd;
printf("read %u bytes\n\r",nd);
return nd; // Returns number of bytes read
}
else { // Remove nd bytes from the input stream
printf("remove\n\r");
dev->bufptr += nd;
return nd;
}
}
Hi, great library!
I see that's its possible to load a image from memory (not spiffs), do you have an example on how this is done?