ImagingDataCommons / highdicom

High-level DICOM abstractions for the Python programming language
https://highdicom.readthedocs.io
MIT License
162 stars 34 forks source link

Improve support to create an ImageFileReader from a DicomFileLike object (i.e. from a byte stream) #294

Open gpizaine opened 2 weeks ago

gpizaine commented 2 weeks ago

Hey there,

I'm trying to read a DICOM file from a byte stream (context: I'm downloading just enough data from large remote DICOM files of several gigabytes to read metadata only), something like:

highdicom.io.ImageFileReader(pydicom.filebase.DicomFileLike(bytes_io))

but faced a few errors. As it's not a common use case, it could be that some code paths are not fully up-to-date.

I've done some investigations and found at least two issues in the ImageFileReader class (io.py). I'm just using highdicom to read metadata, so I can't speak for the whole library, there might be more issues lurking elsewehere:

_FLOAT_PIXEL_DATA_TAGS = {0x7FE00008, 0x7FE00009, }
_UINT_PIXEL_DATA_TAGS = {0x7FE00010, }
_PIXEL_DATA_TAGS = _FLOAT_PIXEL_DATA_TAGS.union(_UINT_PIXEL_DATA_TAGS)

In my case, the Pixel Data tag is (0xE07F, 0x1000), an endianness away from the hard-coded value. Manually adding 0xE07F1000 as a candidate in _UINT_PIXEL_DATA_TAGS solves the issue.

I don't know how much effort is required, but it would be great to improve the support of DicomFileLike objects!

PS: thanks for the amazing library btw :)

CPBridge commented 2 weeks ago

Hi @gpizaine,

Thanks for reporting this issue. I may be wrong here, but I think the issue here is not so much the support for DicomFileLike as the support from reading Big Endian transfer syntaxes in general. Since Big Endian transfer syntaxes have been retired from the standard for a while, and working with them is in general really a pain, we took the decision a while ago not to put the effort into support them. See this comment in the release notes.

Could you please confirm what the transfer syntax of your file is? And also whether the issue is resolved by converting it to a little endian transfer syntax (e.g. like this post).

I'm not totally opposed to small changes that would allow things to work with big endian files, but trying to understand the scope of the problem first. Thanks

CPBridge commented 2 weeks ago

Oh, also, does this work with the same file if you pass the same file as a path, not a DicomFileLike?