Transfersyntax and VR of pixel data

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
Markus Sabin
Posts: 99
Joined: Tue, 2005-07-12, 13:50
Location: Erlangen, Germany

Transfersyntax and VR of pixel data

#1 Post by Markus Sabin »

Dear experts,

I am currently investigating how the requirements of PS3.5, Appendix A are implemented and whether we have to consider them in our code using DCMTK or if DCMTK has built-in methods doing the job.
If I got it correctly, the baseline for Little Endian Implicit/Explicit is:
- if the TS is Explicit Little Endian and the pixeldata is <= 8bpp, VR of pixel data shall be VR_OB
- in all other cases, VR of pixel data shall be VR_OW

The code below illustrates the expectations and observations. It is a minimal working example; my "problem" is in the last line (see comment). My application writes the Image Pixel Module attributes as well which are missing here. But the results are the same, and I cannot see how anything but the VR and the TS are considered when converting the TS.

Code: Select all

    DcmDataset dataset;
    dataset.chooseRepresentation(EXS_LittleEndianImplicit, nullptr);
    std::unique_ptr<char> pixelData (new char[512*512]);

    OFCondition ofResult = dataset.putAndInsertUint16Array(DCM_PixelData, reinterpret_cast<unsigned short*> (pixelData.get()), 512 * 512 / 2);
    DcmElement* element;
    ofResult = dataset.findAndGetElement(DCM_PixelData, element, false);
    DcmEVR valueRep = element->getVR(); // -> VR_OW

    dataset.chooseRepresentation(EXS_LittleEndianExplicit, nullptr);
    dataset.findAndGetElement(DCM_PixelData, element, false); // should not be necessary...but just to make sure
    valueRep = element->getVR(); // expected: VR_OB, actual: VR_OW
Has this been done intentionally? Or am I getting the DICOM Standard wrong? Or is the user of DCMTK expected to take care of the VR conversion?

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

Re: Transfersyntax and VR of pixel data

#2 Post by J. Riesmeier »

Short question: why do you call putAndInsertUint16Array() if the pixel data is 8 bits/pixel?

Addendum: did you get the debug output from this code?

Markus Sabin
Posts: 99
Joined: Tue, 2005-07-12, 13:50
Location: Erlangen, Germany

Re: Transfersyntax and VR of pixel data

#3 Post by Markus Sabin »

Thank you for your counter-questions, Jörg.

Here are the answers:
Short question: why do you call putAndInsertUint16Array() if the pixel data is 8 bits/pixel?
Because PS3.5, A.1c says (for TS Implicit Little Endian): Pixel Data (7FE0,0010) has the Value Representation OW and shall be encoded in Little Endian. This was the first of my tests that you can see in the code: Explicitly set the TS for the DcmDataset to Implicit Little Endian, then assign 8-bit pixel data and verify the VR of the pixel data. However, this yields EVR_OB when it should be EVR_OW. So I think that for correctly encoding <=8 bpp pixel data in Implicit LE, putAndInsertUint16Array must be called.
Addendum: did you get the debug output from this code?
I guess this refers to DcmItem::recalcVR()? Yes, I do see this log output, but it does not occur in the context of the code I posted. I debugged into DcmDataset::chooseRepresentation(), and in this context, DcmPixelData::recalcVR() is called which is much different from DcmItem::recalcVR().

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

Re: Transfersyntax and VR of pixel data

#4 Post by J. Riesmeier »

I guess this refers to DcmItem::recalcVR()?
No, I was referring to line 408 in dcitem.cc, i.e. to DcmItem::checkAndUpdateVR(). Did you get the debug output "DcmItem::checkAndUpdateVR() setting undefined VR of PixelData (7fe0,0010) to 'OW'"?
If not, this might be because this method is only called by the read method and not by the mechanism that is initiated by chooseRepresentation(). Maybe, you could write the implicit VR dataset to a DICOM file and read it again to a DcmFileFormat instance - for testing purposes only, of course.

Markus Sabin
Posts: 99
Joined: Tue, 2005-07-12, 13:50
Location: Erlangen, Germany

Re: Transfersyntax and VR of pixel data

#5 Post by Markus Sabin »

Yes, sorry. checkAndUpdateVR() was what I meant.

I have tried saving and loading, and it works fine. To do so, I had to change the call for setting the (8-bit) pixel data to putAndInsertUint8Array() of course. Then I tried:

Code: Select all

    
    DcmFileFormat file(&dataset);
    ofResult = file.saveFile("e:\\temp\\ELE.dcm", EXS_LittleEndianExplicit);
    ofResult = file.saveFile("e:\\temp\\ILE.dcm", EXS_LittleEndianImplicit);
The pixel data has VR=OB in "ELE.dcm" and VR=OW in "ILE.dcm". The VR is also properly reflected by the DcmPixelData element obtained from the DcmFileFormat after loading the file back into memory. In the scope of executing my changed test method, the message "DcmItem::checkAndUpdateVR() setting undefined VR of PixelData (7fe0,0010) to 'OW'" occurs exactly once which is upon loading the file encoded in Implicit LE (as you have probably expected).

Maybe this side note is also interesting for you. It is really necessary to explicitly specify the output TS for the DcmFileFormat. Although it has been explicitly set for the DcmDataset from which the TS is obtained, it seems to be EXS_Unknown. It happens in DcmFileFormat::write():

Code: Select all

        /* Determine the transfer syntax which shall be used. Either we use the one which was passed, */
        /* or (if it's an unknown transfer syntax) we use the data set's original transfer syntax. */
        E_TransferSyntax outxfer = oxfer;
        if (outxfer == EXS_Unknown && dataset)
            outxfer = dataset->getOriginalXfer();
Although DcmDataset has been assigned a TS, getOriginalXfer() returns EXS_Unknown. getCurrentXfer() returns the last TS set for the dataset as expected. Again, this is just a side note FYI - no comments or responses expected on that.

Baseline (as I see it)
The VR of the pixel data element is correctly written to a file, if:
- the appropriate 8/16 bit method is used for setting the pixel data to the pixel data attribute
- AND the transfer syntax for the output file is properly and explicitly given
Last edited by Markus Sabin on Tue, 2020-04-07, 06:02, edited 1 time in total.

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

Re: Transfersyntax and VR of pixel data

#6 Post by J. Riesmeier »

Thank you for the feedback (and for checking what I was proposing from memory).
In the scope of executing my changed test method, the message "DcmItem::checkAndUpdateVR() setting undefined VR of PixelData (7fe0,0010) to 'OW'" occurs exactly once which is upon loading the file encoded in Implicit LE (as you have probably expected).
Yes, I expected that since the checkAndUpdateVR() is only called by the read method.
Maybe this side note is also interesting for you. It is really necessary to explicitly specify the output TS for the DcmFileFormat. Although it has been explicitly set for the DcmDataset from which the TS is obtained, it seems to be EXS_Unknown.
How did you "explicitly set" the original transfer syntax of the dataset? Did you call DcmDataset::updateOriginalXfer() as it is documented (for datasets that are created in memory)?

The DcmFileFormat::saveFile() method by default writes in the "original transfer syntax" (see documentation).
Although DcmDataset has been assigned a TS, getOriginalXfer() returns EXS_Unknown.
I guess you haven't called DcmDataset::updateOriginalXfer(), right?
Again, this is just a side note FYI - no comments or responses expected on that.
But I did it ;-)

Markus Sabin
Posts: 99
Joined: Tue, 2005-07-12, 13:50
Location: Erlangen, Germany

Re: Transfersyntax and VR of pixel data

#7 Post by Markus Sabin »

Thank you very much for all your help, Jörg!

Now that I know that TS conversion ultimately happens upon writing the dataset to a file or a socket, I have completed my testcases and everything works as expected.

---->SOLVED :D

Thanks again for the great support!

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

Re: Transfersyntax and VR of pixel data

#8 Post by J. Riesmeier »

Now that I know that TS conversion ultimately happens upon writing the dataset to a file or a socket...
Correct. That's where the term "transfer" in "transfer syntax" comes from. What is stored in main memory is the "local syntax".

Glad I could help. Enjoy using DCMTK 8)

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 1 guest