Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading Images from memory #28

Open
glowlabs opened this issue Mar 2, 2018 · 14 comments
Open

Loading Images from memory #28

glowlabs opened this issue Mar 2, 2018 · 14 comments

Comments

@glowlabs
Copy link

glowlabs commented Mar 2, 2018

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?

@sukeshak
Copy link

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

@SmoothWifi
Copy link

Hello,

I try to load jpg img from memory too but with no success:

#include "img1.h" //converted JPG into c array

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?

@sukeshak
Copy link

Don't see anything wrong.
Maybe try the same image with file name to see if that works first?

@SmoothWifi
Copy link

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 :
#include "img1.h"
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?

@sukeshak
Copy link

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.

@SmoothWifi
Copy link

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?

@SmoothWifi
Copy link

Ok I have found it, I am going to study it :)

@SmoothWifi
Copy link

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?

@sukeshak
Copy link

sukeshak commented Sep 26, 2018

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?

@sukeshak
Copy link

Also probably you can try this since bmp is less complicated

TFT_bmp_image

@SmoothWifi
Copy link

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.

@sukeshak
Copy link

Using the BMP function is just to further isolate the issue...

Here is the code you need to debug... good luck :)

void TFT_jpg_image(int x, int y, uint8_t scale, char *fname, uint8_t *buf, int size)

@SmoothWifi
Copy link

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

@SmoothWifi
Copy link

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

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants