bitbank2 / JPEGDEC

An optimized JPEG decoder for Arduino
Apache License 2.0
365 stars 47 forks source link

Problem adding JPEGDEC to an existing library #30

Closed maxmeli123 closed 2 years ago

maxmeli123 commented 2 years ago

Hi bitbank2,

a long story.....

I wrote an optimized library for oled SSD1331 (96x64 16Bit color oled), then ported it to SSD1351 (128x128 16Bit color oled) and even some time ago I started to port for ILI9341 (320x240 touchscreen TFT). These libraries are hardware optimized and works only on ESP8266 and ESP32, they do not worrks on Arduino for now, but because I want to improve performances I do not interested to adapt to slow microcontrollers, maybe in future I will adapt for Teensy that I never used but read that is very fast.

I started to writeSSD1331 library in the 2016, then I optimized to work as fast possible, now my library can play small videos from SD Card or flash at incredibly high framerate, eg. with a small video of 96x54 pixels read from SD can reach 136 FPS. As small I just intend a resolution in pixels and not a duration, these can play long videos even 1 hour and more, the only limitation is the filesystem that do not permit (at least on SD Card) to put big files.

I even wrote an Audio library for ESP8266 and ESP32 and I'm able to play videos at 25-30 FPS with 44100 16Bit Stereo audio out of external I2S audio DAC, I read .wav audio that is placed on SD Card or flash both with video synced, not super perfect but works.

To do this I wrote 2 desktop decoders that read a series of images and pack on a single file in a way that ESP can read as fast possible. These 2 codecs (with GUI and video preview) are pretty the same, but one read Bitmap images, the other read Jpeg images.

Sorry for a long story.... but now I think it is more clear my work.

As Jpeg decoder I've used Bodmer JpegDecoder, but because I will search to optimize and increase a framerate, I compared with other decoders, even your good JPEGDEC.

Your decoder is very very fast, 2 times and more than Bodmer JpegDecoder, so Ive started some days ago to implement it on my SSD1331 library.

Here started my problems.... using a normal sketch (and your example code sketch) all worked but I have some problems implementing it on my library. When started I had problems with static callbacks, then I tried to move callbacks declarations from header file .h to .cpp file, this solved some issues, but I cannot see instance of display library inside callbacks functions because are static methods. Now I tried to create a global instance of display library and use inside callbacks, it see the display functions and the code compiles. The next problem was that when I use JPEGDEC functions for some strange reasons it consume a lot of dynamic memory, like whithout:

the simple sketch I've tried (to just show a jpeg image on the display) consumes 40% of dynamic memory, with these 3 functions it consumes 72%.

Because the library have even a drawBitmap function (as counterpart of drawJpeg) that allocate in ram a full frame (max 96x64 pixels) = 6144 * 2 (because are uint16_t each one) = 12288 bytes, now my library cannot render Jpeg and cannot allocate space for bitmaps, so nothing works.

I'm not expert on C++, searched a lot on the web, but I'm unable to solve these issues.

Please, can you help me... If I send you my library, you can see what is wrong on my code? Can you send me your mail so I can send you my library as attachment of private message?

Note that these libraries are supposed to be released as public domain (full open source) in future to my github repository, but I only can release if they works.

Here my repository: https://github.com/maxmeli123

Many thanks for your precious time and sorry for my not good english but I'm italian.

Have a good day! Massimo

bitbank2 commented 2 years ago

Hi Massimo, My library specifically doesn't allocate any dynamic memory, so it sounds like you're instantiating the class over and over. The easiest way to use my library in your situation is to just use the C interface instead of the C++ class. If you rename jpeg.inl to jpeg.c or just #include it in your code, you can call the C functions directly. There is a single JPEGIMAGE structure that needs 17k of RAM. That's the only memory needed to decode any image. You can allocate this structure statically or dynamically - it's up to you. Take a look in the linux directory to see the simple C example of how to use the code.

maxmeli123 commented 2 years ago

Many thanks, I will try it today and inform you if I've sucess

maxmeli123 commented 2 years ago

Hi Larry,

I've tried your suggestions, replaced the: JPEGDEC jpeg; with JPEGIMAGE jpeg;

Included the 'jpeg.inl' in the header file of my library:

include "JPEGDEC/jpeg.inl"

Replaced all JPEGDEC functions and used the C functions intead of C++ this way:

rc = jpeg.open (TfileName.c_str(), jpgFileOpen, jpgFileClose, jpgFileRead, jpgFileSeek, jpgFileDraw); jpeg.setPixelType(RGB565_BIG_ENDIAN); // We need big endian rc = jpeg.decode (x, y, decoderOptions); jpeg.close();

with:

rc = JPEG_openFile (&jpeg, TfileName.c_str(), jpgFileDraw); JPEG_setPixelType(&jpeg, RGB565_BIG_ENDIAN); // We need big endian rc = JPEG_decode (&jpeg, x, y, decoderOptions); JPEG_close (&jpeg);

commented the C++ declarations in JPEGDEC.h and just leaved uncommented the C declarations (if I do not comment there are conflicts because use of #ifdef __cplusplus) commented all JPEGDEC.cpp file, at this point i think it do not need at all ? It only contains C++ functions (if I do not comment then the compiler says that there are declarations in JPEGDEC.h file because I commented)

.... but apart of lots of 'unused' warnings it won't compile at all, at end of compilation (removed unused warnings) this is the compilation log:

/home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_26856/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x24): undefined reference to _Z13JPEG_openFileP14jpeg_image_tagPKcPFiP13jpeg_draw_tagE' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_26856/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x28): undefined reference to_Z17JPEG_setPixelTypeP14jpeg_image_tagi' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_26856/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x2c): undefined reference to _Z11JPEG_decodeP14jpeg_image_tagiii' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_26856/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x30): undefined reference to_Z17JPEG_getLastErrorP14jpeg_image_tag' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_26856/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x34): undefined reference to _Z10JPEG_closeP14jpeg_image_tag' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_26856/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o: in function_ZN14ESPFastSSD13318drawJpegE6Stringhhji': /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:3366: undefined reference to _Z13JPEG_openFileP14jpeg_image_tagPKcPFiP13jpeg_draw_tagE' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_26856/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o: in function_ZNK6String10startsWithEPKc': /home/massimo/.arduino15/packages/esp8266/hardware/esp8266/3.0.2/cores/esp8266/WString.h:165: undefined reference to _Z17JPEG_setPixelTypeP14jpeg_image_tagi' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/massimo/.arduino15/packages/esp8266/hardware/esp8266/3.0.2/cores/esp8266/WString.h:165: undefined reference to_Z11JPEG_decodeP14jpeg_image_tagiii' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_26856/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o: in function _ZNK6String7wbufferEv': /home/massimo/.arduino15/packages/esp8266/hardware/esp8266/3.0.2/cores/esp8266/WString.h:277: undefined reference to_Z17JPEG_getLastErrorP14jpeg_image_tag' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_26856/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o: in function _ZN14ESPFastSSD13318drawJpegE6Stringhhji': /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:3392: undefined reference to_Z10JPEG_closeP14jpeg_image_tag' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_26856/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o: in function _ZN14ESPFastSSD13315beginEaaj': /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:533: undefined reference to_Z13JPEG_getWidthP14jpeg_image_tag' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_26856/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o: in function _ZN14ESPFastSSD13315beginEaaaaa': /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:534: undefined reference to_Z14JPEG_getHeightP14jpeg_image_tag' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_26856/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o: in function _ZL11jpgFileDrawP13jpeg_draw_tag': /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:536: undefined reference to_Z13JPEG_getWidthP14jpeg_image_tag' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:537: undefined reference to `_Z14JPEG_getHeightP14jpeg_image_tag' collect2: error: ld returned 1 exit status

I've spent last 5 days making it to work, I've tried a lots of solutions but nothing works, I'm very frustated.

I renew my invitation to view the code of my library to see what I'm wrong, otherwise I won't be able to make it to work. If you can't help me in this the only solution available to me is to abandon the idea of using JPEGDEC and continue to use the BodmerJPEGDecoder that is already working but unfortunately it is 2 times slower than your excellent library and it would be a bad thing because I worked last 5 years on this.

Many thanks Massimo

maxmeli123 commented 2 years ago

Apart this I even used callbacks for filesystem to work, but the C code (in the open function) only point to a Draw callback excluding others for file Read, Seek and Close,

bitbank2 commented 2 years ago

The C example compiles without error, so there's nothing specifically wrong with the library code. There are 2 versions of the open function for C, one which assumes RAM/ROM as the input source and the other (JPEG_openFile) which allows file access (written for Linux). To use callbacks, just set them into the JPEGIMAGE structure. I guess I can add a new C function definition for your use case. I had assumed that Arduino would always use the C++ interface. The reason you're getting the compiler errors is that your compiling the code as C++, which causes the C definitions to not get used. Let me make some changes today to correct this.

maxmeli123 commented 2 years ago

Many thanks Larry,

As you said this too could be the problem '(jpeg_openfile) which allows file access (Written for Linux)', so I suppose this loads the image directly from the hard disk and therefore has nothing to do with reading from the Arduino SD card. Note that my library has a complex system to decide which filesystem to use on top of it, it supports SD, SD_MMC, SPIFFS, LittleFS, FFAT, SD_FAT (removed because conflicts with others)this must be defined by the user in the ESPFASTSDSD1331_USERCONFIG.H file by commenting/uncommenting the right #define like this:

define USE_SD // By default use SD

//#define USE_SDMMC
//#define USE_SPIFFS
//#define USE_LITTLEFS //#define USE_FFAT

To read from PROGMEM and RAM (Pixels Array) currently I have not provided anything, this can be done by the user in the main sketch in the traditional way eg. pgm_read_word(&Pixelarray) and draw a single pixel at a time with the function:

bool PushColor (uint16_t Color, bool Swapbytes = false); // Push a single 16 bit pixel

or read the full RAM array and then pass it to the library to draw in a single pass (Very Fast) with the function:

uint16_t Pushcolors (uint16_t * Colors, uint16_t Len, bool Swapbytes = false); // Push a 16 bit pixel array

Anyway I include my library as Zip file, NOT WORKING but last modified to use JPEGDEC so if you make changes for callbacks in the JPEGIMAGE structure you can test yourself if they work on top of an library even if maybe you don't have an SSD1331 oled to test but at least you can see if it compile. In the examples folder I provided a simple sketch specifically to test images (bitmap or jpeg), the name of this sketch is ImageTest.ino

Because I need to protect it before I put on github, the zip file is password protected, I've sent you a private email message with a password, I've just replies to mail that github sent, if you do not receive it please inform me and I will search another way to send this to you.

If there are users interested to this library, please have a little patience, it will be released as soon as possible.

Please, take a look of RawVideoBitmap and RawVideoJpeg classes inside my library folder, with the first one I can read from SD (with ESP8266 @ 160Mhz) and render to dislay an image of 96x54 pixels in just 7-8 milliseconds, because it read indexed images inside a single file (packed with my decoders) with it's single header like a bitmap header with attributes for frame width, height, file size, number of frames etc. With RawVideoJpeg because it uses a lot of seeks (and Bodmer's decoder) the same video show at about 24 fps and I think that when I adapt it with your JPEGDEC it can reach 50 and more fps, so to show a real video framerate (25 fps) I need to add a delay between rendered frames.

I apologize for many comments left in the library and some sample sketches (not all working but some used just to do tests), this is a Working Progress and I left the comments from all changes made in recent years.

A further problem I also found with any decoder is in the slideBitmap and slideJpeg functions that slide images on the screen from left to right, top to bottom etc. because using Pushpixels and Draw MCUsdirectly on oled RAM I need to calculate the right amount of pixels and Crop image MCUs. I made changes to this but it is very far to be perfect, even using bitmaps images because I draw a single image in a single pass.

This SSD1331 is small, with clear colors, true black and very good to make an ESP IOt SmartWatch (but no touch) capable to control remote actuators, show remote sensors, play audio, show images, play videos, make video calls (using ESP32CAM) and more, so for this reason I want to optimize the library to work as fast possible, the SSD1351 too is very good but it is a little big to make a SmartWatch.

Thank you for your help and your excellent, fast and optimized super library. :D

Massimo

file:///home/massimo/Scrivania/ESPFastSSD1331.zip

maxmeli123 commented 2 years ago

Sorry, github or my browser won't upload the zip file, you can downlad it here: https://we.tl/t-WDlVpGZvo4

Because RawVideoJpeg class not already edited to use JPEGDEC (only the oled library use it to draw regular jpeg images) and because I do not removed the RawVideoJpeg class from the library folder and my library have no external depenency but I've put the JPEGDecoder directly inside it and then commented to adapt for JPEGDEC, maybe (much probably) the compiler do not find a JPEGDecoder class and return an error, if this is a case, just put RawVideoJpeg.h and RawVideoJpeg.cpp outside of the library folder so the compiler do not use it at all. Sorry but I forgot to do it myself.

Now I send you an email (as reply of github mail) with the zip password, I'm not sure if this is a right way.... if you do not receive it inform me and I search another way to send, maybe if you can provide your email or other way ...

maxmeli123 commented 2 years ago

Please, when you have some time, can explain how to compile the linux example? I've tried but without success, I'm a very beginner on this, just I typed on terminal the 'make' command but the compiler returned an error that cannot find the image to render.

Many thanks Regards

Massimo

maxmeli123 commented 2 years ago

Hi Larry, are there any develops?

maxmeli123 commented 2 years ago

Please Larry, let me know what is the problem.

I need to know if JPEGDEC can be implemented on my Oled and TFT libraries to speed up Jpeg render.

Many thanks

bitbank2 commented 2 years ago

The compiler errors your saw originally (above in this thread) are due to you trying to link C++ code to C code without the proper function declarations. This is something that I can fix on my side, but please test it first by doing this:

extern "C"{

include "JPEGDEC.h"

} This will tell the compiler to treat all of my C function definitions as C instead of C++.

maxmeli123 commented 2 years ago

Hi Larry,

I've tried your suggestion but still don't compile. I tried other ways but no one works. I think the right way is to use native C ++ and not static C functions, this must be applied to 3 libraries for 3 different displays, and maybe other peoples want integrate the decoder inside other display libraries.

This is my last failure, I've attached the zip file with relevant code. Please, copy the library folder on the Arduino IDE libraries folder, start Arduino IDE, go to the sample codes, look for ESPFastSDSD1331, you will see that it has just one example sketch, ImageTest.ino, that should draw on the OLED an image read from SD Card .. .... but obviously he doesn't do it because does not compile.

Thank you very much.

ESPFastSSD1331.zip

maxmeli123 commented 2 years ago

Please Larry let me know if I have a chance here to use JPEGDEC inside my libraries. I'm very frustated.

Please let me know if you worked around it, or if you plain to work with next days..... I cannot wait anymore, if the problem cannot be solved I need to abandon the idea and use other decoders.

Many thanks

bitbank2 commented 2 years ago

I thought this issue had been settled. The easiest way to do what you want is to create a C file which "includes" my code and then reference them as 'extern "C"' from your C++ code. For example:

create a file called jpegwrapper.c which will consist of 2 lines:

include "JPEGDEC.h"

include "jpeg.inl"

Then you use the JPEGDEC functions from your C++ code by defining them like this:

extern "C" { int JPEG_openFile()... int JPEG_openRAM()... } This will create the proper linkage between C and C++ so the compiler and connect everything.

Obviously you need to create proper function prototypes, not the truncated ones above.

That's it.

maxmeli123 commented 2 years ago

Hi Larry,

I followed all your advices, so I created a file called jpegwrapper.c with the following content:

//#ifndef _JPEGWRAPPER //#define _JPEGWRAPPER

include "JPEGDEC.h"

include "jpeg.inl"

//#endif

Then in the header file of my library I used this:

ifdef FILE_SYSTEM_LOADED

include "JPEGDEC/jpegwrapper.c"

extern "C" {
    #warning "////////// EXTERN C //////////"   // Not a warning, just for DEBUG

    int JPEG_openRAM(JPEGIMAGE *pJPEG, uint8_t *pData, int iDataSize, JPEG_DRAW_CALLBACK *pfnDraw);
    int JPEG_openFile(JPEGIMAGE *pJPEG, const char *szFilename, JPEG_DRAW_CALLBACK *pfnDraw);
    int JPEG_getWidth(JPEGIMAGE *pJPEG);
    int JPEG_getHeight(JPEGIMAGE *pJPEG);
    int JPEG_decode(JPEGIMAGE *pJPEG, int x, int y, int iOptions);
    int JPEG_decodeDither(JPEGIMAGE *pJPEG, uint8_t *pDither, int iOptions);
    void JPEG_close(JPEGIMAGE *pJPEG);
    int JPEG_getLastError(JPEGIMAGE *pJPEG);
    int JPEG_getOrientation(JPEGIMAGE *pJPEG);
    int JPEG_getBpp(JPEGIMAGE *pJPEG);
    int JPEG_getSubSample(JPEGIMAGE *pJPEG);
    int JPEG_hasThumb(JPEGIMAGE *pJPEG);
    int JPEG_getThumbWidth(JPEGIMAGE *pJPEG);
    int JPEG_getThumbHeight(JPEGIMAGE *pJPEG);
    int JPEG_getLastError(JPEGIMAGE *pJPEG);
    void JPEG_setPixelType(JPEGIMAGE *pJPEG, int iType); // defaults to little endian
    void JPEG_setMaxOutputSize(JPEGIMAGE *pJPEG, int iMaxMCUs);
}

//JPEGDEC jpeg; // C++ //JPEGIMAGE jpeg; // C <-- I moved it to my library .cpp file to be static

#define JPEG_DECODER_INITIALIZED
//#define SWAP_BYTES

endif

Compiling the demo sketch that just show a jpeg image the compiler return an error saying that the file is missing, it is used in the FS.h, at this point I tried to change file extension to jpegwrapper.cpp

By making this change the sketch compiles up to around 95%, then show a lots of these errors with 'undefined reference' for any C function:

/home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x6c): undefined reference to JPEG_openFile' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x70): undefined reference toJPEG_setPixelType' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x74): undefined reference to JPEG_decode' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x78): undefined reference toJPEG_getWidth' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x7c): undefined reference to JPEG_getHeight' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x80): undefined reference toJPEG_getBpp' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x84): undefined reference to JPEG_getOrientation' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x88): undefined reference toJPEG_getSubSample' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x8c): undefined reference to JPEG_hasThumb' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x90): undefined reference toJPEG_getThumbWidth' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x94): undefined reference to JPEG_getThumbHeight' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x98): undefined reference toJPEG_getLastError' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o:(.text._ZN14ESPFastSSD13318drawJpegE6Stringhhji+0x9c): undefined reference to JPEG_close' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o: in function_ZN14ESPFastSSD13318drawJpegE6Stringhhji': /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:3346: undefined reference to JPEG_openFile' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:3351: undefined reference toJPEG_setPixelType' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:3352: undefined reference to JPEG_decode' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:3356: undefined reference toJPEG_getWidth' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:3363: undefined reference to JPEG_getHeight' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o: in function_ZNK6String10startsWithEPKc': /home/massimo/.arduino15/packages/esp8266/hardware/esp8266/3.0.2/cores/esp8266/WString.h:165: undefined reference to JPEG_getBpp' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o: in function_ZN14ESPFastSSD13318drawJpegE6Stringhhji': /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:3369: undefined reference to JPEG_getOrientation' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:3372: undefined reference toJPEG_getSubSample' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:3372: undefined reference to JPEG_hasThumb' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:3376: undefined reference toJPEG_getThumbWidth' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:3378: undefined reference to JPEG_getThumbHeight' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:3421: undefined reference toJPEG_getLastError' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:3435: undefined reference to JPEG_close' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /tmp/arduino_build_229422/libraries/ESPFastSSD1331/ESPFastSSD1331.cpp.o: in function_Z11jpgFileDrawP13jpeg_draw_tag': /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:536: undefined reference to JPEG_getWidth' /home/massimo/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/massimo/Arduino/libraries/ESPFastSSD1331/src/ESPFastSSD1331.cpp:536: undefined reference toJPEG_getHeight' collect2: error: ld returned 1 exit status

Something wrong with externalize or maybe the compiler do not like the .cpp extension and expect to be .c because are C functions and I externalize it.

I've attached the project, please can you see what is wrong so we solve once and for all this problem ???

For this problem I've abandoned the long project (from 2016) on this September and I cannot continue without solve it, or just I had to use a slower decoder.

Please help to solve so I can continue to develop opensource code and put it on github, at this point I'm desperate, don't know what else do anything, I've finished my resources on this ...

Many thanks

maxmeli123 commented 2 years ago

Sorry, I had problem to post a file. Here the zip file link: https://ufile.io/v3rsawjz

Many thanks