JPEGDEC
JPEGDEC copied to clipboard
RED tint on image files on Arduino GIGA and I believe Teensy boards as well
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:
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.
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
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
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.
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
I can reproduce the problem - I'll post a fix shortly.
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.