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

EOFException on transcoding of compressed image that is larger when compressed than uncompressed #1411

Open
william00179 opened this issue Mar 27, 2024 · 4 comments · May be fixed by #1414
Open

Comments

@william00179
Copy link

Describe the bug
When reading an instance to transcode that has been compressed such that the resulting pixel item length is greater than the image descriptor length, it leads to an EOFException.

I am trying to process some instances that have been RLE compressed and the compressed pixel data is larger than the input data.

To Reproduce
In the Transcoder class

private void compressPixelData() throws IOException {
        int padding = (int)(this.dis.unsignedLength() - (long)this.imageDescriptor.getLength());

In the normal case reading an uncompressed image, the padding will be 0 or 1.

Reading a compressed image, we would also expect the unsignedLength() to be less than the imageDescriptor.getLength() so this will result in a negative number.

In the normal case, this value returned will be a negative number, 0 or 1.

However, if the compressed pixels actually were larger in size than the uncompressed pixels, it would lead to a very large padding value and when the call is made to skipFully() it will try to skip a large number of bytes and throw the EOFException.

Expected behavior
If the compressed pixel size is larger than the image descriptor length, the dis shouldn't throw an EOFException.

@william00179 william00179 linked a pull request Apr 2, 2024 that will close this issue
@nroduit
Copy link
Member

nroduit commented Apr 6, 2024

Could you provide a sample?

Have you tried transcoding with weasis-dicom-tools

@william00179
Copy link
Author

Sample file for use in the reproducer I'm about to upload.

rle.zip

@william00179
Copy link
Author

Hi @nroduit,

In trying to reproduce this using the dcm2dcm tool I have got some more insight into the issue.

The problem isn't able to be reproduced using the dcm2dcm tool due to it using a FileInputStream. Reading the javadoc for the skip() method here I noted the following

This method may skip more bytes than what are remaining in the backing file. This produces no exception and the number of bytes skipped may include some number of bytes that were beyond the EOF of the backing file. Attempting to read from the stream after skipping past the end will result in -1 indicating the end of the file.

So we get the scenario where the padding value is a large number due to the compressed pixels being actually larger than the uncompressed pixels, the skip function will skip beyond the file EOF and this will work because of the stated behavior of the FileInputStream skip method. However other InputStreams like for example ServletInputStream will throw an EOFException if you try to skip beyond the end of the stream and hence we see this issue.

In the attached reproducer we use the RLE encoded instance that exhibits the condition of being larger compressed than raw. We have a passing test when reading the instance from a FileInputStream, and then a failing test when reading it from different input stream.

reproducer-1411.zip

@nroduit
Copy link
Member

nroduit commented Apr 24, 2024

Thanks for the example. Indeed the problem seems to be in the padding part.

I've also tested weasis-dicom-tools, which has a transcoding part (which could eventually replace the current implementation) and there doesn't seem to be any transcoding problem with this sample.

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

Successfully merging a pull request may close this issue.

2 participants