3.5 SPI Display problem of displaying Jpeg images

Hello David,

Am very thankful for your time, and the Code fix has worked, pictures are showing up much better now, for a minute thought i was doing some mistake in some setting.

What I have is in place of pushRect()

// tft.pushImage(mcu_x, mcu_y, win_w, win_h, pImg);

replaced this line with your code.

So is this like something specific that was required for ili9488 chip.

David or Bodmer

Please answer only when free, it was taking 350ms max to display full image on 2.8 display, but with 3.5 inch display, it's taking 1200ms to display full image, is this normal, both cases spi is operating at 27Mhz

Thank you very much.

ILI9488 needs 320x480x3 SPI bytes.
ILI9341 needs 240x320x2 SPI bytes e.g. 350ms.

This means 1050ms for the bigger picture. Purely because of more SPI traffic.

Obviously a fixed pushImage() will be faster than the individual pushColor() calls in my kludge.

There is plenty of scope for optimisation. Actually the SPI traffic maths calculation is naive. The bulk of the time is spent decoding JPG and creating the 16-bit or 24-bit pixel.

David.

Thanks David, actually it was taking 1.7 to 2.2 seconds, depending on picture, but 1.686 is minimum on Esp32, The spi frequency change did not make much of difference hardly 100ms. so looks like it is taking lot of cpu for jpeg decode conversion. Well It should be ok for now.

I have found the problem. Edit TFT_eSPI.h
from

  // Convert swapped byte 16 bit colour to 18 bit and write in 3 bytes
  #define tft_Write_16S(C) spi.transfer(C & 0xF8); \
                           spi.transfer((C & 0xE0)>>11 | (C & 0x07)<<5); \
                           spi.transfer((C & 0x1F00)>>5)

to:

  // Convert swapped byte 16 bit colour to 18 bit and write in 3 bytes
  #define tft_Write_16S(C) spi.transfer(C & 0xF8); \
                           spi.transfer((C & 0xE000)>>11 | (C & 0x07)<<5); \
                           spi.transfer((C & 0x1F00)>>5)

It makes little difference using pushRect(), pushImage(), pushColors(..., false) or pushColor() in a loop.
sunfl.jpg takes 2293ms, 2293ms, 2287ms, 2293ms on an ESP8266

Most of the time is spent in decoding JPEG.
ESP32 will be faster than ESP8266.

There might be optimisations for the JPEG decode algorithm.

Personally, I find the convenience of SPIFFS to be impressive. You can get lots of JPEGS into a 1MB SPIFFS. Of course an SD card gives you unlimited quantity of pictures and you can use RAW pixel dumps.

On balance, a compressed JPG avoids the SPI transfer time of a RAW file from SD.
The ESP32 supports QSPI SD card. I have never tried QSPI.

David.

David, am gonna try that fix first in the morning, yes am using SPIFFS only, and 1MB is enough to rotate like 10 pics, and any supported graphic files. SD card is not required at this point, The time taken for JPEG C Array is at 700ms so the important one file am gonna call from Array for now and rest from SPIFFS, that would solve the time issue.

I have removed the old fix and applied new one by changing the below line , the images are fine , displaying normally, the jpeg which was taking 2.2 sec is now taking just one second, this has lot of detail etc.
Thank you again, the problem is solved.

spi.transfer((C & 0xE000)

I am impressed. I only ran it on ESP8266. I would not expect such a big difference.

If you tried the ZIP that I had attached, it reports files found on SPIFFS. And the rendering time for each file that matches the strstr() line. e.g. strstr("sunfl.jpg")

In other words. You could quote the actual number of milliseconds for "sunfl.jpg"
We could compare the same JPEG image.

David.

David, the kbv code required changes to run on esp32, so I have used the old same sketch to display sunfl.jpg , SPIFFS_Jpeg sketch from examples of jpegdecoder , the performance difference between esp32 and esp8266 should not be that much but the time is 700ms

===========================
Drawing file: /sunfl.jpg

===============
JPEG image info

Width :320
Height :480
Components :1
MCU / row :20
MCU / col :30
Scan type :4
MCU width :16
MCU height :16

Total render time was : 730 ms

david_prentice:
I have found the problem. Edit TFT_eSPI.h

...

Library has been updated, thanks David.

This is the result from the ESP8266 using ESP8266 v2.4.2 Core

NodeMCU decoder test!

Initialisation done.

SPIFFS files found:
=====================================
  File name               Size
=====================================
/Baboon40.jpg            24384 bytes
/waterlily.jpg           44762 bytes
/bapa.jpg                26797 bytes
/betty_8.jpg             17422 bytes
/chinese_girl.jpg        46034 bytes
/woof.jpg                19000 bytes
/dog.jpg                 18163 bytes
/EagleEye.jpg            20838 bytes
/flower.jpg              23879 bytes
/flower3.jpg             32385 bytes
/flower4.jpg             30836 bytes
/hibiscus.jpg            26372 bytes
/lena20k.jpg             19414 bytes
/tiger_320x200x24.jpg    29484 bytes
/marilyn_240x240.jpg     9402 bytes
/MOTO_CORRIDA.jpg        18450 bytes
/Mouse480.jpg            6609 bytes
/Parrot2.jpg             17393 bytes
/Penguins.jpg            29719 bytes
/purple.jpg              32042 bytes
/rose.jpg                9243 bytes
/sunfl.jpg               32187 bytes
/tiger.jpg               31171 bytes
/angry_16.jpg            18267 bytes
=====================================

  1: /Baboon40.jpg        320x480 2320 ms
  2: /waterlily.jpg       400x300 2052 ms
  3: /bapa.jpg            250x315 1245 ms
  4: /betty_8.jpg         204x252 823 ms
  5: /chinese_girl.jpg    320x480 2502 ms
  6: /woof.jpg            240x320 1218 ms
  7: /dog.jpg             284x177 824 ms
  8: /EagleEye.jpg        300x300 1336 ms
  9: /flower.jpg          240x320 1261 ms
 10: /flower3.jpg         320x240 1329 ms
 11: /flower4.jpg         320x240 1310 ms
 12: /hibiscus.jpg        240x320 1282 ms
 13: /lena20k.jpg         320x480 2247 ms
 14: /tiger_320x200x24.jpg 320x200 1154 ms
 15: /marilyn_240x240.jpg 240x240 861 ms
 16: /MOTO_CORRIDA.jpg    320x240 1211 ms
 17: /Mouse480.jpg        480x320 2078 ms
 18: /Parrot2.jpg         261x200 875 ms
 19: /Penguins.jpg        320x240 1305 ms
 20: /purple.jpg          240x320 1333 ms
 21: /rose.jpg            176x220 611 ms
 22: /sunfl.jpg           320x480 2292 ms
 23: /tiger.jpg           320x240 1330 ms
 24: /angry_16.jpg        240x320 1179 ms

I had already updated ESP32 to ESP32 Core v1.0.2
I had to amend the SPIFFS calls to suit v1.0.2
and this is the result for ESP32 using ESP32 Core v1.0.2 @ 240MHz SPI=27MHz

NodeMCU decoder test!

Initialisation done.
Listing directory: /
  FILE: /angry_16.jpg	SIZE: 18267
  FILE: /Baboon40.jpg	SIZE: 24384
  FILE: /bapa.jpg	SIZE: 26797
  FILE: /betty_8.jpg	SIZE: 17422
  FILE: /chinese_girl.jpg	SIZE: 46034
  FILE: /dog.jpg	SIZE: 18163
  FILE: /EagleEye.jpg	SIZE: 20838
  FILE: /flower.jpg	SIZE: 23879
  FILE: /flower3.jpg	SIZE: 32385
  FILE: /flower4.jpg	SIZE: 30836
  FILE: /hibiscus.jpg	SIZE: 26372
  FILE: /lena20k.jpg	SIZE: 19414
  FILE: /marilyn_240x240.jpg	SIZE: 9402
  FILE: /MOTO_CORRIDA.jpg	SIZE: 18450
  FILE: /Mouse480.jpg	SIZE: 6609
  FILE: /Parrot2.jpg	SIZE: 17393
  FILE: /Penguins.jpg	SIZE: 29719
  FILE: /purple.jpg	SIZE: 32042
  FILE: /rose.jpg	SIZE: 9243
  FILE: /sunfl.jpg	SIZE: 32187
  FILE: /tiger.jpg	SIZE: 31171
  FILE: /tiger_320x200x24.jpg	SIZE: 29484
  FILE: /waterlily.jpg	SIZE: 44762
  FILE: /woof.jpg	SIZE: 19000
  1: /angry_16.jpg        240x320 394 ms
  2: /Baboon40.jpg        320x480 771 ms
  3: /bapa.jpg            250x315 453 ms
  4: /betty_8.jpg         204x252 273 ms
  5: /chinese_girl.jpg    320x480 868 ms
  6: /dog.jpg             284x177 275 ms
  7: /EagleEye.jpg        300x300 445 ms
  8: /flower.jpg          240x320 418 ms
  9: /flower3.jpg         320x240 478 ms
 10: /flower4.jpg         320x240 473 ms
 11: /hibiscus.jpg        240x320 463 ms
 12: /lena20k.jpg         320x480 750 ms
 13: /marilyn_240x240.jpg 240x240 287 ms
 14: /MOTO_CORRIDA.jpg    320x240 401 ms
 15: /Mouse480.jpg        480x320 695 ms
 16: /Parrot2.jpg         261x200 289 ms
 17: /Penguins.jpg        320x240 470 ms
 18: /purple.jpg          240x320 479 ms
 19: /rose.jpg            176x220 203 ms
 20: /sunfl.jpg           320x480 802 ms
 21: /tiger.jpg           320x240 477 ms
 22: /tiger_320x200x24.jpg 320x200 415 ms
 23: /waterlily.jpg       400x300 712 ms
 24: /woof.jpg            240x320 403 ms

Note that the ESP32 was faster than ESP8266 but I did not get 730 ms

 20: /sunfl.jpg           320x480 802 ms

I updated my ESP8266 installation to v2.5.1 but could not get any TFT_eSPI examples to compile.
I will try installing v2.5.0. Otherwise I will have to go back to v2.4.2

David.

Edit. Woo-hoo. ESP8266 v2.5.0 will compile and run but it is very SLOW. e.g. sunfl.jpg: 3677 ms @ 160MHz. 4418 ms @ 80MHz ( SPI=27MHz )

Using library JPEGDecoder at version 1.8.0 in folder: C:\Users\David Prentice\Documents\Arduino\libraries\JPEGDecoder 
Using library SD at version 1.0.5 in folder: C:\Users\David Prentice\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\libraries\SD 
Using library SPI at version 1.0 in folder: C:\Users\David Prentice\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\libraries\SPI 
Using library TFT_eSPI at version 1.4.9 in folder: C:\Users\David Prentice\Documents\Arduino\libraries\TFT_eSPI 
"C:\\Users\\David Prentice\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\2.5.0-3-20ed2b9/bin/xtensa-lx106-elf-size" -A "C:\\Users\\DAVIDP~1\\AppData\\Local\\Temp\\arduino_build_573353/TFT_SPIFFS_Jpeg_kbv.ino.elf"
Sketch uses 332688 bytes (31%) of program storage space. Maximum is 1044464 bytes.
Global variables use 31364 bytes (38%) of dynamic memory, leaving 50556 bytes for local variables. Maximum is 81920 bytes.

Sorry, my spi is at 40Mhz, at some point I was testing and left it there, that's why 730ms.

Same sketch and same jpeg retested at 27Mhz, it matches now.

===========================
Drawing file: /sunfl.jpg

===============
JPEG image info

Width :320
Height :480
Components :1
MCU / row :20
MCU / col :30
Scan type :4
MCU width :16
MCU height :16

Total render time was : 801 ms

I have amended the sketch for conditional ESP32 / ESP8266 SPIFFS methods
Tested on ESP32 v1.0.2 and ESP8266 v2.4.2

ESP8266 v2.5.0 builds but is SLOW
ESP8266 v2.5.1 does not compile any TFT_eSPI examples

Please can you try it on your ESP32.

There is conditional code for rendering individual JPEG tile.
I have fixed the odd-width tile display. Look at betty_8.jpg or bapa.jpg

David.

TFT_SPIFFS_Jpeg_kbv.zip (568 KB)

Looks like am at these versions as per Board manager, should I update them, did not want to break stuff.

Esp8266 2.4.2
Esp32 on 1.0.1

Test output ESP32 / 3.5 Inch SPI display 320x480

⸮ ⸮,$C⸮*⸮P⸮⸮⸮⸮eM⸮NodeMCU decoder test!

Initialisation done.

SPIFFS files found:

File name Size

/angry_16.jpg 18267 bytes
/Baboon40.jpg 24384 bytes
/bapa.jpg 26797 bytes
/betty_8.jpg 17422 bytes
/chinese_girl.jpg 46034 bytes
/dog.jpg 18163 bytes
/EagleEye.jpg 20838 bytes
/flower.jpg 23879 bytes
/flower3.jpg 32385 bytes
/flower4.jpg 30836 bytes
/hibiscus.jpg 26372 bytes
/lena20k.jpg 19414 bytes
/marilyn_240x240.jpg 9402 bytes
/MOTO_CORRIDA.jpg 18450 bytes
/Mouse480.jpg 6609 bytes
/Parrot2.jpg 17393 bytes
/Penguins.jpg 29719 bytes
/purple.jpg 32042 bytes
/rose.jpg 9243 bytes
/sunfl.jpg 32187 bytes
/tiger.jpg 31171 bytes
/tiger_320x200x24.jpg 29484 bytes
/waterlily.jpg 44762 bytes
/woof.jpg 19000 bytes

1: /angry_16.jpg 240x320 394 ms
2: /Baboon40.jpg 320x480 773 ms
3: /bapa.jpg 250x315 458 ms
4: /betty_8.jpg 204x252 277 ms
5: /chinese_girl.jpg 320x480 870 ms
6: /dog.jpg 284x177 279 ms
7: /EagleEye.jpg 300x300 450 ms
8: /flower.jpg 240x320 419 ms
9: /flower3.jpg 320x240 479 ms
10: /flower4.jpg 320x240 474 ms
11: /hibiscus.jpg 240x320 465 ms
12: /lena20k.jpg 320x480 751 ms
13: /marilyn_240x240.jpg 240x240 287 ms
14: /MOTO_CORRIDA.jpg 320x240 402 ms
15: /Mouse480.jpg 480x320 696 ms
16: /Parrot2.jpg 261x200 294 ms
17: /Penguins.jpg 320x240 471 ms
18: /purple.jpg 240x320 480 ms
19: /rose.jpg 176x220 203 ms
20: /sunfl.jpg 320x480 802 ms
21: /tiger.jpg 320x240 479 ms
22: /tiger_320x200x24.jpg 320x200 416 ms
23: /waterlily.jpg 400x300 715 ms
24: /woof.jpg 240x320 405 ms

Stick with ESP8266 v2.4.2

At least the sketch appears to have worked out of the box.

"output.h" contains my results.

SPIFFS is "built-in" to the ESP8266 core.
SPIFFS is a "built-in" library for ESP32

It is unfortunate that you have to use different calls to walk a directory.
I would be happier if I could avoid conditional code.

David.

I recommend using the jpeg rendering code incorporated into the TFT_eFEX extension library which can be added to the start of a sketch like this:

// Invoke TFT library
TFT_eSPI tft = TFT_eSPI();

// https://github.com/Bodmer/TFT_eFEX
#include <TFT_eFEX.h>              // Include the extension graphics functions library
TFT_eFEX  fex = TFT_eFEX(&tft);    // Create TFT_eFX object "efx" with pointer to "tft" object

The examples show the use of the rendering functions.

It is simplest to use pushImage() for rendering MCU blocks as this function will crop blocks correctly if they overlap the edges of the screen.

Since images may not have a width and/or height that is a whole number of MCU blocks (for example dividable by 16) so in the worst case may only contain 1 pixel. Early versions of the jpeg rendering code did not take this into account, but this is handled in the TFT_eFEX library.

The ESP32 board package includes a native jpeg decoder that is slightly (~12%) faster than the JPEGDecoder library but is less memory efficient. The TFT_eFEX "Jpeg_ESP32" demonstrates the new functions and includes cropping and scaling of the jpeg.

The TFT_eSPI library has been tweaked to be compatible with the ESP8266 latest board package. This version is not yet available via te IDE library manager so you would need to download direct from Git.

Havve you ever tried Chan's tjpgd decoder?
Is it faster than picojpeg ?

It would be nice to use with Xmega or smaller M0 chips.

David.

Hi David, Espressif appear to have used the tjpgd decoder code and embedded it in the board package. Based on ESP32 experience it is ~12% faster probably because picojpeg uses 8 bit variables where possible (as it targeted 8 bit MCUs).

Use of the tjpgd decoder with Xmega and M0 would be possible but I am not a user of those processors so it is not something I plan to investigate.

Ah-ha. I have just Forked TFTeFEX. So I can write an equivalent "show all JPEGs on SPIFFS" sketch.

If it looks promising, I can port from ESP32 C++ code easier than fiddling with Chan's example in C.

Chan's examples are very much tied to specific hardware.

On a different subject. When I attempted to install ESP8266 2.5.1 or 2.5.0 the rendering speed became very SLOW. I have not investigated.

David.

Here is a test sketch that should run on both ESP32 and ESP8266
ESP32 version compares both styles of Jpeg method.
ESP8266 only uses the JPEGDecoder method.

================================================
ESP32 v1.02 @ 240MHz
Using library JPEGDecoder at version 1.8.0
Using library TFT_eSPI at version 1.4.9 
Using library TFT_eFEX at version 0.0.4
User Setup: SPI=27MHz ILI9488=320x480
================================================

ESP8266 / ESP32 Jpeg decoder test!

Initialisation done.

Listing SPIFFS files:
=================================================
  File name                Size
=================================================
  /angry_16.jpg                         18267 bytes
  /Baboon40.jpg                         24384 bytes
  /bapa.jpg                             26797 bytes
  /betty_8.jpg                          17422 bytes
  /chinese_girl.jpg                     46034 bytes
  /dog.jpg                              18163 bytes
  /EagleEye.jpg                         20838 bytes
  /flower.jpg                           23879 bytes
  /flower3.jpg                          32385 bytes
  /flower4.jpg                          30836 bytes
  /hibiscus.jpg                         26372 bytes
  /lena20k.jpg                          19414 bytes
  /marilyn_240x240.jpg                   9402 bytes
  /MOTO_CORRIDA.jpg                     18450 bytes
  /Mouse480.jpg                          6609 bytes
  /Parrot2.jpg                          17393 bytes
  /Penguins.jpg                         29719 bytes
  /purple.jpg                           32042 bytes
  /rose.jpg                              9243 bytes
  /sunfl.jpg                            32187 bytes
  /tiger.jpg                            31171 bytes
  /tiger_320x200x24.jpg                 29484 bytes
  /waterlily.jpg                        44762 bytes
  /woof.jpg                             19000 bytes
=================================================

render from array in Flash
scaled and cropped from array in Flash

render files from SPIFFS:
  1: /angry_16.jpg        240x320 392 ms [348 ms]
  2: /Baboon40.jpg        320x480 767 ms [674 ms]
  3: /bapa.jpg            250x315 452 ms [417 ms]
  4: /betty_8.jpg         204x252 273 ms [247 ms]
  5: /chinese_girl.jpg    320x480 864 ms [763 ms]
  6: /dog.jpg             284x177 275 ms [248 ms]
  7: /EagleEye.jpg        300x300 455 ms [392 ms]
  8: /flower.jpg          240x320 417 ms [364 ms]
  9: /flower3.jpg         320x240 477 ms [424 ms]
 10: /flower4.jpg         320x240 472 ms [419 ms]
 11: /hibiscus.jpg        240x320 463 ms [410 ms]
 12: /lena20k.jpg         320x480 746 ms [661 ms]
 13: /marilyn_240x240.jpg 240x240 286 ms [253 ms]
 14: /MOTO_CORRIDA.jpg    320x240 400 ms [352 ms]
 15: /Mouse480.jpg        480x320 692 ms [451 ms]
 16: /Parrot2.jpg         261x200 290 ms [253 ms]
 17: /Penguins.jpg        320x240 470 ms [417 ms]
 18: /purple.jpg          240x320 478 ms [423 ms]
 19: /rose.jpg            176x220 203 ms [177 ms]
 20: /sunfl.jpg           320x480 810 ms [711 ms]
 21: /tiger.jpg           320x240 476 ms [421 ms]
 22: /tiger_320x200x24.jpg 320x200 414 ms [367 ms]
 23: /waterlily.jpg       400x300 710 ms [543 ms]
 24: /woof.jpg            240x320 402 ms [353 ms]

TFT_FEX_SPIFFS_Jpeg.ino

/*====================================================================================

           Test jpeg rendering with ESP8266 and JPEGDecoder library

  ==================================================================================*/

// The Jpeg library required can be found here:
// https://github.com/Bodmer/JPEGDecoder

// The example images used to test this sketch can be found in the sketch
// Data folder, press Ctrl+K to see this folder. Use the IDE "Tools" menu
// "ESP8266 Sketch Data Upload" option to upload the images to SPIFFS.

// An image is also stored as an array in a header file attached to this sketch
#include "jpeg_arrays.h"

//====================================================================================
//                                  Libraries
//====================================================================================
// Call up the SPIFFS FLASH filing system this is part of the ESP Core
#define FS_NO_GLOBALS
#include <FS.h>

#include <SPI.h>

// https://github.com/Bodmer/TFT_eSPI
#include <TFT_eSPI.h>                 // Hardware-specific library
TFT_eSPI tft = TFT_eSPI();            // Invoke custom library

// https://github.com/Bodmer/TFT_eFEX
#include <TFT_eFEX.h>              // Include the extension graphics functions library
TFT_eFEX  fex = TFT_eFEX(&tft);    // Create TFT_eFX object "efx" with pointer to "tft" object


//====================================================================================
//                                    Setup
//====================================================================================
void setup()
{
    //Serial.begin(250000); // Used for messages and the C array generator
    Serial.begin(9600); // Used for messages

    delay(10);
    Serial.println("\nESP8266 / ESP32 Jpeg decoder test!");

    tft.begin();

    tft.setRotation(0);  // 0 & 2 Portrait. 1 & 3 landscape

    tft.fillScreen(TFT_BLACK);

    if (!SPIFFS.begin()) {
        Serial.println("SPIFFS initialisation failed!");
        while (1) yield(); // Stay here twiddling thumbs waiting
    }
    Serial.println("\r\nInitialisation done.");

    fex.listSPIFFS(); // Lists the files so you can see what is in the SPIFFS

    Serial.println("render from array in Flash");
    fex.drawJpeg(EagleEye, sizeof(EagleEye), 0, 0);

#if defined(ESP32)
    Serial.println("scaled and cropped from array in Flash");
    // Power of 2 scale factors
    /*0  JPEG_DIV_NONE,
      1  JPEG_DIV_2,
      2  JPEG_DIV_4,
      3  JPEG_DIV_8,
      4  JPEG_DIV_MAX // = DIV_16 */

    // Scaled and cropped from array
    fex.drawJpg(EagleEye, sizeof(EagleEye), 0, 240,
                120, 120, 60, 60, JPEG_DIV_2);
#endif
    delay(2000);
    Serial.println("");
    Serial.println("render files from SPIFFS:");
}

//====================================================================================
//                                    Loop
//====================================================================================
int imagecnt;
void doSomething(const char *name)
{
    boolean decoded = JpegDec.decodeFsFile(name);
    if (decoded == false) return;
    tft.setRotation(JpegDec.width > JpegDec.height ? 1 : 0);
    tft.fillScreen(random(0xFFFF));
    int t1 = millis(), t2 = 0;
    fex.drawJpeg(name, 0, 0);
    t1 = millis() - t1;
#if defined(ESP32)
    delay(1000);
    tft.fillScreen(random(0xFFFF));
    t2 = millis();
    fex.drawJpgFile(SPIFFS, name, 0, 0);
    t2 = millis() - t2;
#endif
    char buf[80];
    sprintf(buf, "%3d: %-20s %dx%d %d ms [%d ms]",
            ++imagecnt, name, JpegDec.width, JpegDec.height, t1, t2);
    Serial.println(buf);
    delay(2000);
}

//====================================================================================
//                                    Loop
//====================================================================================
#if defined(ESP32)
void loop()
{
    File directory = SPIFFS.open("/");
    File f;
    while (f = directory.openNextFile()) {
        String bum = f.name();
        const char *s = bum.c_str();
        if (strstr(s, ".jpg") != NULL) {
            doSomething(s);
        }
    }
}
#else   //old ESP8266 has different SPIFFS methods
void loop()
{
    fs::Dir directory = SPIFFS.openDir("/");
    while (directory.next()) {
        String bum = directory.fileName();
        const char *s = bum.c_str();
        if (strstr(s, ".jpg") != NULL) {
            doSomething(s);
        }
    }
}
#endif
//====================================================================================

Edit. Another day. I have concluded:

  1. the new ESP32 decode is about 10% faster than the JPEGDecoder version
  2. the JPEGDecoder version still has issues with part tiles e.g. betty_8 and bapa
  3. the new version crops landscape Mouse and waterlily to width=320
  4. my sketch crashes after a while on ESP8266. I have not investigated yet