Closed robtinkers closed 1 month ago
I'm sorry, I don't have an easy way to test this setup. I have MacOS and Linux and it doesn't segfault on either. Can you try adding some printf statements to narrow down where the error is?
In all 4 test cases (jpegdec without an argument, and also with demo.jpg / perf.jpg / squirrel_dither.jpg as an argument), the seg fault occurs when y=0 x=8 in DecodeJPEG().
Specifically, it is in the memset() near the top of JPEGDecodeMCU():
} else { // decode all the AC coefficients
printf("JPEGDecodeMCU:memset() %p %d\n", pMCU, 64*sizeof(short));
memset(pMCU, 0, 64*sizeof(short)); // pre-fill with zero since we may skip coefficients
printf("JPEGDecodeMCU:memset() done\n");
pEnd2 = (uint8_t *)&cZigZag2[64];
}
So:
$ ./jpegdec
--- DELETED ---
DecodeJPEG() y=0 x=6
JPEGDecodeMCU:pMCU initialised 0x5580dfb1a340
JPEGDecodeMCU:memset() 0x5580dfb1a340 128
JPEGDecodeMCU:memset() done
--- DELETED ---
JPEGDecodeMCU:pMCU initialised 0x5580dfb1a5c0
JPEGDecodeMCU:memset() 0x5580dfb1a5c0 128
JPEGDecodeMCU:memset() done
DecodeJPEG() y=0 x=7
JPEGDecodeMCU:pMCU initialised 0x5580dfb1a340
JPEGDecodeMCU:memset() 0x5580dfb1a340 128
JPEGDecodeMCU:memset() done
--- DELETED ---
JPEGDecodeMCU:pMCU initialised 0x5580dfb1a5c0
JPEGDecodeMCU:memset() 0x5580dfb1a5c0 128
JPEGDecodeMCU:memset() done
DecodeJPEG() y=0 x=8
JPEGDecodeMCU:pMCU initialised 0x108110a110a210c2
JPEGDecodeMCU:memset() 0x108110a110a210c2 128
Segmentation fault
And:
$ ./jpegdec ../demo.jpg
--- DELETED ---
JPEGDecodeMCU:pMCU initialised 0x56091ed455c0
JPEGDecodeMCU:memset() 0x56091ed455c0 128
JPEGDecodeMCU:memset() done
DecodeJPEG() y=0 x=8
JPEGDecodeMCU:pMCU initialised 0x8c708c708c508c50
JPEGDecodeMCU:memset() 0x8c708c708c508c50 128
Segmentation fault
$ ./jpegdec ../perf.jpg
--- DELETED ---
JPEGDecodeMCU:pMCU initialised 0x559bf9cc75c0
JPEGDecodeMCU:memset() 0x559bf9cc75c0 128
JPEGDecodeMCU:memset() done
DecodeJPEG() y=0 x=8
JPEGDecodeMCU:pMCU initialised 0xffffffffffffffff
JPEGDecodeMCU:memset() 0xffffffffffffffff 128
Segmentation fault
$ ./jpegdec ../squirrel_dither.jpg
--- DELETED ---
JPEGDecodeMCU:pMCU initialised 0x560d287f55c0
JPEGDecodeMCU:memset() 0x560d287f55c0 128
JPEGDecodeMCU:memset() done
DecodeJPEG() y=0 x=8
JPEGDecodeMCU:pMCU initialised 0xee95ee95ee95ee95
JPEGDecodeMCU:memset() 0xee95ee95ee95ee95 128
Segmentation fault
(The bad pMCU pointer values are consistent between runs.)
Decoding to a file still seems to work:
$ ./jpegdec ../demo.jpg demo.bmp
--- DELETED ---
JPEGDecodeMCU:memset() 0x55f5d2b035c0 128
JPEGDecodeMCU:memset() done
DecodeJPEG() y=0 x=8
JPEGDecodeMCU:pMCU initialised 0x55f5d2b03340
JPEGDecodeMCU:memset() 0x55f5d2b03340 128
JPEGDecodeMCU:memset() done
JPEGDecodeMCU:pMCU initialised 0x55f5d2b033c0
JPEGDecodeMCU:memset() 0x55f5d2b033c0 128
JPEGDecodeMCU:memset() done
JPEGDecodeMCU:pMCU initialised 0x55f5d2b03440
JPEGDecodeMCU:memset() 0x55f5d2b03440 128
JPEGDecodeMCU:memset() done
JPEGDecodeMCU:pMCU initialised 0x55f5d2b034c0
JPEGDecodeMCU:memset() 0x55f5d2b034c0 128
JPEGDecodeMCU:memset() done
JPEGDecodeMCU:pMCU initialised 0x55f5d2b03540
JPEGDecodeMCU:memset() 0x55f5d2b03540 128
JPEGDecodeMCU:memset() done
JPEGDecodeMCU:pMCU initialised 0x55f5d2b035c0
JPEGDecodeMCU:memset() 0x55f5d2b035c0 128
JPEGDecodeMCU:memset() done
DecodeJPEG() y=0 x=9
JPEGDecodeMCU:pMCU initialised 0x55f5d2b03340
JPEGDecodeMCU:memset() 0x55f5d2b03340 128
--- DELETED ---
$ ls -l demo.bmp
-rw-r--r-- 1 rob rob 1346266 Sep 25 16:57 demo.bmp
... but the image is corrupt when loaded into IrfanView. (My bad, should have actually checked yesterday!)
Are you running the latest code from this repo or the version in the Arduino library manager? I don't see how this can occur. Do you have another OS where you can test this? WSL inside of Windows doesn't give me confidence that it's some other issue outside of my code.
I'm running the 1.6.1 release, specifically https://github.com/bitbank2/JPEGDEC/archive/refs/tags/1.6.1.tar.gz
.
I just created a fresh install of "Ubuntu Server (minimized)" inside VirtualBox, and added the build-essential package:
rob@vmdevbox:~/JPEGDEC-1.6.1/linux$ sudo apt update && sudo apt upgrade
--- DELETED ---
The following upgrades have been deferred due to phasing:
python3-distupgrade ubuntu-release-upgrader-core
0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.
rob@vmdevbox:~/JPEGDEC-1.6.1/linux$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 24.04.1 LTS
Release: 24.04
Codename: noble
rob@vmdevbox:~/JPEGDEC-1.6.1/linux$ make
cc -c -Wall -O2 -I../src -D__LINUX__ main.c
In file included from main.c:11:
../src/jpeg.inl: In function ‘JPEGIDCT’:
../src/jpeg.inl:2264:9: warning: unused variable ‘iCol’ [-Wunused-variable]
2264 | int iCol;
| ^~~~
../src/jpeg.inl:2263:19: warning: unused variable ‘ucColMask’ [-Wunused-variable]
2263 | unsigned char ucColMask;
| ^~~~~~~~~
../src/jpeg.inl: At top level:
../src/jpeg.inl:755:16: warning: ‘readFLASH’ defined but not used [-Wunused-function]
755 | static int32_t readFLASH(JPEGFILE *pFile, uint8_t *pBuf, int32_t iLen)
| ^~~~~~~~~
../src/jpeg.inl: In function ‘JPEGFilter’:
../src/jpeg.inl:1421:25: warning: ‘xmmIn’ is used uninitialized [-Wuninitialized]
1421 | __m128i xmmFF = _mm_cmpeq_epi8(xmmIn, xmmIn);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/jpeg.inl:1420:17: note: ‘xmmIn’ was declared here
1420 | __m128i xmmIn, xmmOut;
| ^~~~~
cc main.o -lm -lpthread -o jpegdec
rob@vmdevbox:~/JPEGDEC-1.6.1/linux$ ./jpegdec
JPEG decoder demo
options:
Run without parameters to test in-memory decoding
Pass a single filename to test decoding performance
Pass 2 filenames to convert a JPEG file to a BMP file
e.g. ./jpegdec <infile.jpg> <outfile.bmp>
Segmentation fault (core dumped)
(Note that I haven't verified that the seg fault is for the same reason as under WSL.)
Current JPEGDEC-master also seg faults.
Can you clone the current code (not the current released version)?
Also seg faults, I'm afraid.
I added code to make the MCU buffer 16-byte aligned for S3 SIMD (and others). There is plenty of space for 64 x 6 values + 8 shorts to allow for alignment. It really makes no sense that this is segfaulting unless the MCU pointer is never set or the pointer is getting corrupted after the first pass.
I'm able to recreate this on my Linux machine; I'll figure it out.
ok, fixed it :) It was a wrong offset in the SSE code for 4:2:0 RGB565 output. Please clone and retest.
Great! I can confirm that jpegdec doesn't seg fault under WSL or Linux for me.
I'm sorry to report, though, that the decoded bitmaps (./jpegdec ../demo.jpg demo.bmp
etc.) are still corrupt on both platforms.
Corrupt doesn't mean anything by itself. Can you give me an example? Also try disabling the SIMD by setting "NO_SIMD".
Away from my PC for a bit. Are you unable to reproduce?
I normally don't work on my x64 laptop; that's why this error exists. Give me an example of 'corruption'.
(Had a weekend away.)
Thank you! All seems good now.
I downloaded the v1.6.1 release inside the Windows Subsystem for Linux on my PC, ran 'make' inside the linux folder, but the resulting 'jpegdec' crashes with a segmentation fault.
My PC is running Windows 10 (fully updated), WSL is Ubuntu 22.04.5 LTS (fully updated) on x86_64, cc is "cc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0"
I do get a few warnings on compilation (I have added -Wextra here, but the seg faults still happen without):
And the segmentation faults:
A trace:
But decoding does seem to work: