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

RED tint on image files on Arduino GIGA and I believe Teensy boards as well #70

Open
KurtE opened this issue Feb 3, 2024 · 13 comments
Open

Comments

@KurtE
Copy link
Contributor

KurtE commented Feb 3, 2024

I am currently running on Version 1.4.1 - I tried to sync up and build with your current sources.
(last change) Fix 64 bit support - and I am getting compiler errors.

All of the JPEG files are now seeing a RED tint, like:
image

Others are seeing it as well up on Arduino forum:
https://forum.arduino.cc/t/display-jpg-from-a-sd-card/1204519/26

Not sure if this helps, but this sketch is setup to run on Arduino GIGA with the GIGA shield. (I was seeing it as well when displaying on ILI9341).

tft_picture_view_sd_giga_shield-240203a.zip

PNG files with your decoder appear OK, also BMP files that I load directly also look fine.
image

Small-Drake


2401C188 Loading JPG image 'Small-Drake.jpg' 54453
Image size: 400x320Scale: 1/1 Image Offsets (200, 80)
!!File:Small-Drake.jpg Time:332 writeRect calls:0

This one was loaded from SD Card, can also load them from USB memory stick (which is slower) on GIGA.

Let me know if you need any additional information

@KurtE
Copy link
Contributor Author

KurtE commented Feb 3, 2024

Quick update, I just synced the sources again as I see a couple of commits...
Still does not build:

"C:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\arm-none-eabi-gcc\\7-2017q4/bin/arm-none-eabi-g++" -c -x assembler-with-cpp -mcpu=cortex-m7 -mfpu=fpv5-d16 -DARDUINO=10607 -DARDUINO_GIGA -DARDUINO_ARCH_MBED_GIGA -DARDUINO_ARCH_MBED "-IC:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_giga\\4.0.10\\cores\\arduino" "-IC:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_giga\\4.0.10\\variants\\GIGA" "-Ic:\\Users\\kurte\\Documents\\Arduino\\libraries\\Arduino_USBHostMbed5\\src" "-IC:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_giga\\4.0.10\\libraries\\SPI" "-Ic:\\Users\\kurte\\Documents\\Arduino\\libraries\\SdFat_real\\src" "-Ic:\\Users\\kurte\\Documents\\Arduino\\libraries\\elapsedMillis" "-Ic:\\Users\\kurte\\Documents\\Arduino\\libraries\\GIGA_digitalWriteFast" "-Ic:\\Users\\kurte\\Documents\\Arduino\\libraries\\JPEGDEC\\src" "-Ic:\\Users\\kurte\\Documents\\Arduino\\libraries\\PNGdec\\src" "-Ic:\\Users\\kurte\\Documents\\Arduino\\libraries\\Arduino_GigaDisplay_GFX\\src" "-IC:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_giga\\4.0.10\\libraries\\Arduino_H7_Video\\src" "-Ic:\\Users\\kurte\\Documents\\Arduino\\libraries\\Adafruit_GFX_Library" "-Ic:\\Users\\kurte\\Documents\\Arduino\\libraries\\Adafruit_BusIO" "-IC:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_giga\\4.0.10\\libraries\\Wire" "-IC:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_giga\\4.0.10\\libraries\\Portenta_SDRAM\\src" "-IC:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_giga\\4.0.10\\libraries\\ea_malloc" -DCM4_BINARY_START=0x60000000 -DCM4_BINARY_END=0x60040000 -DCM4_RAM_END=0x60080000 "-IC:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_giga\\4.0.10\\cores\\arduino/api/deprecated" "-IC:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_giga\\4.0.10\\cores\\arduino/api/deprecated-avr-comp" "-iprefixC:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_giga\\4.0.10\\cores\\arduino" "@C:\\Users\\kurte\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_giga\\4.0.10\\variants\\GIGA/../GIGA/includes.txt" "c:\\Users\\kurte\\Documents\\Arduino\\libraries\\JPEGDEC\\src\\s3_simd_dequant.S" -o "C:\\Users\\kurte\\AppData\\Local\\Temp\\arduino\\sketches\\1B3D878E0D4E79C3B2F3E4B9EAB8241D\\libraries\\JPEGDEC\\s3_simd_dequant.S.o"
In file included from c:\Users\kurte\Documents\Arduino\libraries\JPEGDEC\src\JPEGDEC.cpp:32:0:
c:\Users\kurte\Documents\Arduino\libraries\JPEGDEC\src\jpeg.inl: In function 'int JPEGMakeHuffTables(JPEGIMAGE*, int)':
c:\Users\kurte\Documents\Arduino\libraries\JPEGDEC\src\jpeg.inl:1116:37: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
             if (iTable * HUFF11SIZE >= sizeof(pJPEG->usHuffAC) / 2)
                 ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
c:\Users\kurte\Documents\Arduino\libraries\JPEGDEC\src\jpeg.inl: In function 'void JPEGIDCT(JPEGIMAGE*, int, int)':
c:\Users\kurte\Documents\Arduino\libraries\JPEGDEC\src\jpeg.inl:2204:17: error: 'ucMaxACCol' was not declared in this scope
     ucColMask = ucMaxACCol | 1; // column 0 must always be calculated
                 ^~~~~~~~~~
c:\Users\kurte\Documents\Arduino\libraries\JPEGDEC\src\jpeg.inl:2210:19: error: 'ucMaxACRow' was not declared in this scope
             if (!(ucMaxACRow & (1<<iCol))) // simpler calculations if only half populated
                   ^~~~~~~~~~
c:\Users\kurte\Documents\Arduino\libraries\JPEGDEC\src\jpeg.inl: In function 'void JPEGPixelLE(uint16_t*, int, int, int)':
c:\Users\kurte\Documents\Arduino\libraries\JPEGDEC\src\jpeg.inl:2703:40: warning: left shift of negative value [-Wshift-negative-value]
     uint32_t ulTmp = -1409 | (-2925 << 16); // for green calc
                                        ^~
c:\Users\kurte\Documents\Arduino\libraries\JPEGDEC\src\jpeg.inl: In function 'void JPEGPixel2LE(uint16_t*, int, int, int, int)':
c:\Users\kurte\Documents\Arduino\libraries\JPEGDEC\src\jpeg.inl:2779:48: warning: left shift of negative value [-Wshift-negative-value]
     uint32_t ulTmp2, ulTmp = -1409 | (-2925 << 16); // for green calc
                                                ^~
c:\Users\kurte\Documents\Arduino\libraries\JPEGDEC\src\JPEGDEC.cpp: In member function 'void JPEGDEC::setFramebuffer(void*)':
c:\Users\kurte\Documents\Arduino\libraries\JPEGDEC\src\JPEGDEC.cpp:36:5: error: 'JPEG_setFramebuffer' was not declared in this scope
     JPEG_setFramebuffer(&_jpeg, pFramebuffer);
     ^~~~~~~~~~~~~~~~~~~
c:\Users\kurte\Documents\Arduino\libraries\JPEGDEC\src\JPEGDEC.cpp:36:5: note: suggested alternative: 'setFramebuffer'
     JPEG_setFramebuffer(&_jpeg, pFramebuffer);
     ^~~~~~~~~~~~~~~~~~~
     setFramebuffer
Multiple libraries were found for "SdFat.h"
  Used: C:\Users\kurte\Documents\Arduino\libraries\SdFat_real
  Not used: C:\Users\kurte\Documents\Arduino\libraries\SdFat_-_Adafruit_Fork
Using library Arduino_USBHostMbed5 at version 0.3.1 in folder: D:\github\Arduino_USBHostMbed5 

image

@bitbank2
Copy link
Owner

bitbank2 commented Feb 3, 2024

What pixel type are you outputting? Can you share the calls you're making to the library? I've been testing on ESP32-S3 hardware, but I can switch back to M7.
The latest changes aren't in the release build and are for desktop PC optimizations.

@KurtE
Copy link
Contributor Author

KurtE commented Feb 3, 2024

Again Note: current code does not build on GIGA nor Teensy MicroMod or 3.6

#if !defined (HAS_SSE) && !defined(HAS_NEON)
    // do columns first
    ucColMask = ucMaxACCol | 1; // column 0 must always be calculated
    for (iCol = 0; iCol < 8 && ucColMask; iCol++)
    {
        if (ucColMask & (1<<iCol)) // column has data in it
        {
            ucColMask &= ~(1<<iCol); // unmark this col after use
            if (!(ucMaxACRow & (1<<iCol))) // simpler calculations if only half populated

ucMaxACRow is not defined...

Here is some of the code calling it:

void processJPGFile(WrapperFile &jpgFile, const char *name, bool fErase) {
  int image_size = jpgFile.size();
  jpgFile.seek(0);
  Serial.println();
  Serial.print((uint32_t)&jpgFile, HEX);
  Serial.print(F(" Loading JPG image '"));
  Serial.print(name);
  Serial.print("' ");
  Serial.println(image_size, DEC);
  uint8_t scale = 1;
  if (jpeg.open((void *)&jpgFile, image_size, nullptr, myReadJPG, mySeekJPG, JPEGDraw)) {
    int image_width = jpeg.getWidth();
    int image_height = jpeg.getHeight();
    int decode_options = 0;
    Serial.print("Image size: ");
    Serial.print(image_width);
    Serial.print("x");
    Serial.print(image_height);
    switch (g_JPGScale) {
      case 1:
        scale = 1;
        decode_options = 0;
        break;
      case 2:
        scale = 2;
        decode_options = JPEG_SCALE_HALF;
        break;
      case 4:
        scale = 4;
        decode_options = JPEG_SCALE_QUARTER;
        break;
      case 8:
        scale = 8;
        decode_options = JPEG_SCALE_EIGHTH;
        break;
      default:
        {
          if ((image_width > g_jpg_scale_x_above[SCL_16TH]) || (image_height > g_jpg_scale_y_above[SCL_16TH])) {
            decode_options = JPEG_SCALE_EIGHTH | JPEG_SCALE_HALF;
            scale = 16;
          } else if ((image_width > g_jpg_scale_x_above[SCL_EIGHTH]) || (image_height > g_jpg_scale_y_above[SCL_EIGHTH])) {
            decode_options = JPEG_SCALE_EIGHTH;
            scale = 8;
          } else if ((image_width > g_jpg_scale_x_above[SCL_QUARTER]) || (image_height > g_jpg_scale_y_above[SCL_QUARTER])) {
            decode_options = JPEG_SCALE_QUARTER;
            scale = 4;
          } else if ((image_width > g_jpg_scale_x_above[SCL_HALF]) || (image_height > g_jpg_scale_y_above[SCL_HALF])) {
            decode_options = JPEG_SCALE_HALF;
            scale = 2;
          }
        }
    }
    if (fErase && ((image_width / scale < g_tft_width) || (image_height / scale < g_tft_height))) {
      tft.fillScreen((uint16_t)g_background_color);
    }

    if (g_center_image) {
      g_image_offset_x = (g_tft_width - image_width / scale) / 2;
      g_image_offset_y = (g_tft_height - image_height / scale) / 2;
    } else {
      g_image_offset_x = 0;
      g_image_offset_y = 0;
    }
    g_image_scale = scale;
    Serial.print("Scale: 1/");
    Serial.print(g_image_scale);
    Serial.print(" Image Offsets (");
    Serial.print(g_image_offset_x);
    Serial.print(", ");
    Serial.print(g_image_offset_y), Serial.println(")");

    jpeg.decode(0, 0, decode_options);
    jpeg.close();
  } else {
    Serial.println("Was not a valid jpeg file");
  }
  jpgFile.close();
}


int32_t myReadJPG(JPEGFILE *pjpegfile, uint8_t *buffer, int32_t length) {
  if (!pjpegfile || !pjpegfile->fHandle) return 0;
  return ((WrapperFile *)(pjpegfile->fHandle))->read(buffer, length);
}
int32_t mySeekJPG(JPEGFILE *pjpegfile, int32_t position) {
  if (!pjpegfile || !pjpegfile->fHandle) return 0;
  return ((WrapperFile *)(pjpegfile->fHandle))->seek(position);
}

int JPEGDraw(JPEGDRAW *pDraw) {
  if (g_debug_output) {
    Serial.print("jpeg draw: x,y=");
    Serial.print(pDraw->x);
    Serial.print(",");
    Serial.print(pDraw->y);
    Serial.print(", cx,cy = ");
    Serial.print(pDraw->iWidth);
    Serial.print(",");
    Serial.println(pDraw->iHeight);
  }
  writeClippedRect(pDraw->x, pDraw->y, pDraw->iWidth, pDraw->iHeight, pDraw->pPixels);
  return 1;
}
#endif

@bitbank2
Copy link
Owner

bitbank2 commented Feb 3, 2024

I can reproduce the problem - I'll post a fix shortly.

@bitbank2
Copy link
Owner

bitbank2 commented Feb 4, 2024

I pushed a fix which temporarily disables the M4/M7 SIMD code. The problem started when Teensyduino removed the M4 intrinsics. I added my own and perhaps the definitions are not equivalent. I'll continue to investigate.

@wdx04
Copy link

wdx04 commented Jun 10, 2024

Got the same problem on a NUCLEO-F413ZH board. Disabling SIMD fixed the problem, though the decoding time is longer(49630 us to decode a 14K 120x180 image without SIMD, compared to 45340 us when SIMD is used).

@bitbank2
Copy link
Owner

bitbank2 commented Jun 10, 2024

Are you using the release version or what's on Github at the moment? @wdx04

@wdx04
Copy link

wdx04 commented Jun 10, 2024

Are you using the release version or what's on Github at the moment? @wdx04

I think I'm using the current master branch.
I download the code as a zip file earlier this year, the JPEGDEC-master folder inside the zip file was last modified at March 23.

@bitbank2
Copy link
Owner

bitbank2 commented Jun 10, 2024

Correction - I didn't push the fix yet because I have a bunch of new functionality that I am unsure about giving away for free. I've had second thoughts about everyone using my work and I get nothing in return.

@bitbank2
Copy link
Owner

I guess I can cherry pick this particular fix, hang on

@bitbank2
Copy link
Owner

ok, try it now

@wdx04
Copy link

wdx04 commented Jun 10, 2024

ok, try it now

Thank you.
There is a compilation error at line 2781, because the 'ulTmp' variable is undefined:

uint32_t ulTmp2 = 0xfa7f /*-1409*/ | 0xf4930000 /*(-2925 << 16)*/; // for green calc     

I tried to fix the error and recompile:

uint32_t ulTmp2, ulTmp = 0xfa7f /*-1409*/ | 0xf4930000 /*(-2925 << 16)*/; // for green calc     

But the decoded images seem to be unaffected by the fix, I still see red images after the fix.

@bitbank2
Copy link
Owner

ok, thanks for trying. I need to set up a build environment and PCB to test these for all pixel types. I had given up on using CM4 SIMD because it's nearly useless.

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