Embedding a precompressed JPEG in a DICOM

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
CodeLogic
Posts: 4
Joined: Mon, 2005-05-16, 22:39

Embedding a precompressed JPEG in a DICOM

#1 Post by CodeLogic »

Hi,

I'm interested in embedding (encapsulating) a precompressed JPEG (that has been compressed outside dcmtk) as it is without any modification inside a freshly creatly DICOM image. What kind of transfer syntax would I need to use? Also, how would the code be?

If this is not possible, how do I embed a raw RGB into DCM_PixelData and convert that to JPEG? I have managed to create a valid DICOM image with uncompressed RGB in DCM_PixelData. I'd like to replace this raw data with precompressed data (compressed outside dcmtk). When I try to change the transfer syntax using the following:

Code: Select all

DJEncoderRegistration::registerCodecs();
OFCondition cond;
.
.
// embed all the necessary info like DCM_PixelRepresentation,
// DCM_PixelData, etc (basically everything so that sending it 
// uncompressed works correctly).
.
.
DJ_RPLossy params(90);
cond = dataset->chooseRepresentation(EXS_JPEGProcess1TransferSyntax, &params);
I get an illegal call error (ECC_IllegalCall) in the text field of OFCondition. Obviously, I'm doing something majorly wrong.

I'd prefer a solution for embedding a precompressed JPEG into the DICOM image.

Thanks a lot for any help in advance.

Cheers!!

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#2 Post by Jörg Riesmeier »

An example is provided in "dcmdata/apps/xml2dcm.cc" (search for "pixel").

CodeLogic
Posts: 4
Joined: Mon, 2005-05-16, 22:39

#3 Post by CodeLogic »

Thanks for the tip. I read through the source and I think I'm on the right track now, but I'm still facing some problems.

Code: Select all

E_TransferSyntax xfer = DcmXfer(EXS_JPEGProcess1TransferSyntax).getXfer();
DcmDataset *dataset = _fileformat->getDataset();
.
.
// input image metadata and UIDs
.
.
DcmElement *newPixelData = new DcmPixelData(DcmTag(DCM_PixelDataGroupLength, EVR_UL));

cond = dataset->insert(newPixelData, OFTrue);
DcmPixelSequence *sequence = new DcmPixelSequence(DcmTag(DCM_PixelData, EVR_OB));
OFstatic_cast(DcmPixelData *, newPixelData)->putOriginalRepresentation(xfer, NULL, sequence);
DcmPixelItem *newItem = new DcmPixelItem(DcmTag(DCM_Item, EVR_OB));
cond = sequence->insert(newItem);
cond = newItem->putUint8Array((const Uint8 *)GetOriginal(), GetOriginalSize()); // returns the precompressed JPEG blob

DJ_RPLossy params(90);
cond = dataset->chooseRepresentation(xfer, &params);

_fileformat->saveFile("filename.dcm", EXS_JPEGProcess1TransferSyntax);
The file that gets written is only 1KB. No error is returned during any step. I use 'medcon' to view DICOM image metadata and here's what I get:

Code: Select all

(0010,0020) LO[1] PatientID: [123456789] (10 bytes)
(0010,0030) DA[1] PatientsBirthDate: [20050518] (8 bytes)
(0010,0040) CS[1] PatientsSex: [Male] (4 bytes)
(0018,0015) CS[1] BodyPartExamined: [asdf] (4 bytes)
(0028,0002) US[1] SamplesPerPixel: 3 (2 bytes)
(0028,0004) CS[1] PhotometricInterpretation: [RGB] (4 bytes)
(0028,0006) US[1] PlanarConfiguration: 0 (2 bytes)
(0028,0010) US[1] Rows: 480 (2 bytes)
(0028,0011) US[1] Columns: 640 (2 bytes)
(0028,0030) DS[1] PixelSpacing: [0.0611111111 0.0611111111] (26 bytes)
(0028,0100) US[1] BitsAllocated: 8 (2 bytes)
(0028,0101) US[1] BitsStored: 8 (2 bytes)
(0028,0102) US[1] HighBit: 7 (2 bytes)
(0028,0103) US[1] PixelRepresentation: 0 (2 bytes)
(0032,000C) CS[1] StudyPriorityID: [ASAP] (4 bytes)
(0032,1030) LO[1] ReasonForStudy: [af] (2 bytes)
(7FE0,0000) UL[1] PixelDataGroupLength: 0 (4 bytes)
May 18 16:04:59 log[1928]: error: No images found

(process:1928): (X)MedCon-WARNING **: Reading: DICM Error reading file
Any idea why PixelDataGroupLength is being set to '0' even though I'm performing the following:

Code: Select all

DcmElement *newPixelData = new DcmPixelData(DcmTag(DCM_PixelDataGroupLength, EVR_UL));
cond = dataset->insert(newPixelData, OFTrue);
DcmPixelSequence *sequence = new DcmPixelSequence(DcmTag(DCM_PixelData, EVR_OB));
OFstatic_cast(DcmPixelData *, newPixelData)->putOriginalRepresentation(xfer, NULL, sequence);
DcmPixelItem *newItem = new DcmPixelItem(DcmTag(DCM_Item, EVR_OB));
cond = sequence->insert(newItem);
cond = newItem->putUint8Array((const Uint8 *)GetOriginal(), GetOriginalSize()); // returns the precompressed JPEG blob
Thanks again for any help.

Marco Eichelberg
OFFIS DICOM Team
OFFIS DICOM Team
Posts: 1445
Joined: Tue, 2004-11-02, 17:22
Location: Oldenburg, Germany
Contact:

#4 Post by Marco Eichelberg »

You are mixing Pixel Data (DCM_PixelData, attribute tag is 7FE0,0010) and Pixel Data Group Length (DCM_PixelDataGroupLength, attribute tag is 7FE0,0000).

CodeLogic
Posts: 4
Joined: Mon, 2005-05-16, 22:39

#5 Post by CodeLogic »

I actually tried using 'DCM_PixelDataGroupLength' because I noticed it in a valid DICOM file containing an encapsulated item. However, after changing it to 'DCM_PixelData', I get the encapsulated item in the file. However, 'medcon' compains with error: No images found.

Code: Select all

(0028,0002) US[1] SamplesPerPixel: 3 (2 bytes)
(0028,0004) CS[1] PhotometricInterpretation: [RGB] (4 bytes)
(0028,0006) US[1] PlanarConfiguration: 0 (2 bytes)
(0028,0010) US[1] Rows: 480 (2 bytes)
(0028,0011) US[1] Columns: 640 (2 bytes)
(0028,0030) DS[1] PixelSpacing: [0.0611111111 0.0611111111] (26 bytes)
(0028,0100) US[1] BitsAllocated: 8 (2 bytes)
(0028,0101) US[1] BitsStored: 8 (2 bytes)
(0028,0102) US[1] HighBit: 7 (2 bytes)
(0028,0103) US[1] PixelRepresentation: 0 (2 bytes)
(0032,000C) CS[1] StudyPriorityID: [ASAP] (4 bytes)
(0032,1030) LO[1] ReasonForStudy: [asdf] (4 bytes)
(7FE0,0010) OB[1] PixelData: (undefined length)
(FFFE,E000) UN[1] Encapsulated Item: (10246 bytes)
(FFFE,E0DD) UN[0] Encapsulated SequenceDelimitationItem: (no value)
May 19 09:48:22 log[2536]: error: No images found

(process:2536): (X)MedCon-WARNING **: Reading: DICM Error reading file
I'm using the same image attributes as I would have if I was sending the DICOM file uncompressed (unencapsulated) and using the EXS_JPEGProcess1TransferSyntax transfer syntax, since the encapsulated item is RGB 8-bits/sample JPEG with lossy compression. Are there any other requirements to be met in order to send the image successfully.

Marco Eichelberg
OFFIS DICOM Team
OFFIS DICOM Team
Posts: 1445
Joined: Tue, 2004-11-02, 17:22
Location: Oldenburg, Germany
Contact:

#6 Post by Marco Eichelberg »

Are there any other requirements to be met in order to send the image successfully.
This is not really a DCMTK related question, is it. I would suggest you re-read the definition of encapsulated pixel data in part 5 of the DICOM standard, in particular with regard to the so-called offset table.

CodeLogic
Posts: 4
Joined: Mon, 2005-05-16, 22:39

#7 Post by CodeLogic »

Thanks, that worked! I had misread that the entire offset table was optional, but only the value seems to be optional. The JPEG gets encapsulated correctly, however, since 'medcon' does not support lossy JPEGs, I cannot view it. That's not a problem. I have a question regarding transmission of this file however :)

I'm setting the transfer syntax of the dataset to JPEGProcess25_27TransferSyntax and while saving the file with dataset->saveFile(), also using the same transfer syntax. However when I attempt to send this file to a DICOM server using storescu and the following command:

Code: Select all

storescu.exe <ip> 104 -aet TEST -d <file.dcm>
it complains about not being able to convert the transfer Syntax to LittleEndianExplicit. Why is attempting to perform this conversion?

Code: Select all

Transfer: JPEGFullProgression:Hierarchical:Process25+27 ->  LittleEndianExplicit
Store SCU RQ: MsgID 1, (SC) XMIT:DIMSE Warning: (NMTEST,ANY-SCP): sendMessage: unable to convert dataset from 'JPEG Full Progression, Hierarchical, Process 25+27' transfer syntax to 'LittleEndianExplicit'.
Does the DICOM server need to support receiving the file in the JPEGProcess25_27TransferSyntax tansfer syntax (only receiving, since processing, after it is received, is performed by another application)?

Thanks again !

Marco Eichelberg
OFFIS DICOM Team
OFFIS DICOM Team
Posts: 1445
Joined: Tue, 2004-11-02, 17:22
Location: Oldenburg, Germany
Contact:

#8 Post by Marco Eichelberg »

Does the DICOM server need to support receiving the file in the JPEGProcess25_27TransferSyntax tansfer syntax (only receiving, since processing, after it is received, is performed by another application)?
Yes, this is how the DICOM network protocol works. The transfer syntax needs to be negotiated between SCU and SCP, and the default is uncompressed transmission. In your case, the association negotiation results in a presentation context that would allow uncompressed transmission of the SOP class you use. Since StoreSCU cannot find a way of sending the image "as is", it checks if there is a way to convert the image from the original form to the form needed for transmission. For this purpose, DCMTK maintains a list of codecs. Since this list is always empty in StoreSCU, the error message looks like the one you see.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest