Handling PixelData after change in 3.6.5

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
jakecobb
Posts: 3
Joined: Thu, 2016-09-08, 15:55

Handling PixelData after change in 3.6.5

#1 Post by jakecobb » Thu, 2021-06-03, 18:24

We have some long-existing code that uses DcmItem::findAndGetUint8Array for DCM_PixelData. Prior to DCMTK 3.6.5 this function and the similar ones for e.g. uint16 array always returned the length of the array. 3.6.5 introduced this change:

https://support.dcmtk.org/redmine/issues/867

Some relevant commits:

b4ca1a8daff5f261e37361bd2538f10a42bc2468
15226ccc2c8020b2ebd9fa501bf564eb8baf9432


This had the surprising (to me anyway) breaking change of "count" now returning the number of items, which is VR-dependent, instead of the length of the data array.

PixelData can be OB or OW encoded, but we were always using the uint8 form and reading the appropriate chunks according to BitsAllocated, etc. I believe you have to do this regardless because BitsAllocated can be higher than 16 bit but the VR will never be OL (32-bit) or OV (64-bit), or it could be something like 24 that doesn't align with any of these larger VRs.

So, a few questions then:
  • The backwards incompatibility is not addressed in the release notes, was it intentional and what's the reasoning?
  • Can we still use DcmItem::findAndGetUint8Array for variable-VR items like PixelData?
  • If so, what is the proper way to get the length of the data array regardless of e.g. OB vs OW?
  • If not, what is the expected way to handle the variable-VR of PixelData uniformly?

J. Riesmeier
DCMTK Developer
Posts: 2299
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: Handling PixelData after change in 3.6.5

#2 Post by J. Riesmeier » Mon, 2021-06-07, 13:02

Thank you for the detailed report.
The backwards incompatibility is not addressed in the release notes, was it intentional and what's the reasoning?
It was not intentional. On the other hand, using findAndGetUint8Array() for OW data elements was also not intended as the API documentation says: "Applicable to the following VRs: OB"
The reason why this method should not be used for OW data is the byte-ordering, i.e. little endian vs. big endian. Both the DICOM dataset and the architecture on the system the software runs on could use any of them.
Can we still use DcmItem::findAndGetUint8Array for variable-VR items like PixelData?
You can but I would not recommend it. The documentation of the "count" parameter says (and also said this for previous versions of the DCMTK): "stores number of items in the result array (if not NULL)". For OW data, the number of items is not identical to the number of bytes needed to store the data. This is what you've experienced when upgrading the version of the DCMTK to 3.6.5 (or newer).
If so, what is the proper way to get the length of the data array regardless of e.g. OB vs OW?
Count is not length (in bytes) as I said. If you are interested in the number of bytes of the data element value, you should e.g. call getLenght() on the DcmElement instance.
If not, what is the expected way to handle the variable-VR of PixelData uniformly?
The answer depends on what you mean by "uniformly". I don't think that you can avoid to distinguish different cases, e.g. OB and OW for the PixelData element. This is e.g. also done by the DicomImage class, which tries to hide the complexity of the DICOM image format to the user, at least for display purposes (rendering).

Post Reply

Who is online

Users browsing this forum: Baidu [Spider], Google [Bot] and 1 guest