Efferent-Health / fo-dicom.Codecs

Cross-platform Dicom native codecs for fo-dicom
Other
64 stars 22 forks source link

Crash when encoding to JPEGLSLossless or JPEGLSNearLossless #68

Open TheMcCann7 opened 2 months ago

TheMcCann7 commented 2 months ago

Describe the bug When encoding to JPEGLSLossless or JPEGLSNearLossless, it will seemingly crash at random times. It's not always the same image in an image series that will crash. This doesn't happen with the JPEG2000 encoders on the same image series. I was testing with standard MRI and CT series.

To Reproduce Iterate through each image in an image series using fo-dicom, and then re-encode each to JPEG-LS. Eventually, it will catastrophically crash with no exception that I can catch in .NET.

Example code:

DicomFile dicomFile = DicomFile.Open(dicomFilePath, FileReadOption.ReadAll);
compressedDicomFile = dicomFile.Clone(DicomTransferSyntax.JPEGLSLossless);

If I perform a GC.Collect() between each re-encoding, it actually works fine. This led me to be suspicious of managed memory being used by unmanaged code that wasn't being properly pinned or fixed with the garbage collector. After glancing through the Encode() method in https://github.com/Efferent-Health/fo-dicom.Codecs/blob/master/Codec/DicomJpegLsCodec.cs, I think there might be some memory management issues that were introduced by the introduction of the ArrayPool. For example, newJpegData is being rented from the ArrayPool multiple times, but is only returned once at the end of the method. I tried going back to a version before the ArrayPool changes, but they don't support .NET Framework, so I couldn't verify if that was the issue.

Environment:

aerik commented 1 week ago

Did you ever get any further on this, or are you just calling GC.Collect() ?

TheMcCann7 commented 1 week ago

I decided to use a different encoding (JPEGProcess14SV1). It's not as good as JPEGLSLossless, but I feel a lot safer using it instead of relying on GC.Collect().