Discussion Forum for OFFIS DICOM Tools - For registration, send email with desired user name to the OFFIS DICOM team
It is currently Sat, 2017-02-25, 15:07

All times are UTC + 1 hour

Post new topic Reply to topic  [ 3 posts ] 
Author Message
PostPosted: Thu, 2015-09-10, 18:49 

Joined: Thu, 2012-10-25, 07:18
Posts: 4
I have a JPEG 2000 byte stream, which, if I dump to disk with a 'jp2' extension, reads as a JPEG image. I'd like though to create an uncompressed (EXS_LittleEndianExplicit) DICOM file. So far, I can only create a compressed Dicom file, which reads in fine in Matlab, but gives the following error using dcmdjp2k (I have purchased the JPEG codecs):
I: reading input file test2.dcm
D: DcmItem::checkTransferSyntax() TransferSyntax="Little Endian Explicit"
I: decompressing file
cannot get marker segment
F: JPEG 2000 codec error: decompressing file: test2.dcm

Note that the transfer syntax of "Little Endian Explicit" might be a clue as to why dcmdjp2k cannot read the image, but Matlab can. I'm hoping in the forum to get some clues as to what might be wrong. Here are my steps (where tmpBuffer is the JPEG 2000 byte stream). Note, that the general method is taken from insertEncapsulatedPixelData.

1) Register codecs:
D2DecoderRegistration::registerCodecs(opt_uidcreation, opt_planarconfig);
and check dictionary is loaded.

2) Create DcmFileFormat
DcmFileFormat fileformat;
DcmDataset *pDataset = fileformat.getDataset();
// TODO: Prepare JPEG codec parameters (DJ_RPLossless or DJ_RPLossy) and call DcmDataset's chooseRepresentation method, just as in dcmcjpeg.
// DcmFileFormat dcmff(pDataset);
pDataset->chooseRepresentation( outputTS, NULL );

3) Create pixel sequence, add table offset, then store compressed data in the sequence (should DcmOffsetList dummyList; be more appropriately set?):
cond = pixelSequence->storeCompressedFrame(dummyList, tmpBuffer, numTmpBytes, 0);

4) insert pixel data attribute incorporating pixel sequence into dataset

5) Tell pixel data element that this is the original presentation of the pixel data and how it compressed:
pixelData->putOriginalRepresentation(EXS_JPEG2000, NULL, pixelSequence);
cond = pDataset->insert(pixelData);

6) Set all relevant tags, columns, rows, bits, samples, photometric interp etc.

7) Decompress (this fails):
cond = pDataset->chooseRepresentation(EXS_LittleEndianExplicit, NULL);

8) Debug, dump dicom that is readable by Matlab:
fileformat.saveFile("test2.dcm", JPEG2000);

Any help or suggestions would be appreciated! Thank you.

PostPosted: Mon, 2015-09-14, 09:24 

Joined: Tue, 2004-11-02, 17:22
Posts: 1195
Location: Oldenburg, Germany
Thanks for sending us the sample file, and code. There are two problems with the compressed image file. This first one is quite simple: The offset table, i.e. the (normally empty) first item containing the jump offsets into the compressed image are missing. If I dump your file, the output looks like this
(7fe0,0010) OB (PixelSequence #=1)                      # u/l, 1 PixelData
 (fffe,e000) pi 00\00\00\0c\6a\50\20\20\0d\0a\87\0a\00\00\00\14\66\74\79\70\6a\70... # 45422, 1 Item
(fffe,e0dd) na (SequenceDelimitationItem)               #   0, 0 SequenceDelimitationItem

while it should correctly look like this.
(7fe0,0010) OB (PixelSequence #=2)                      # u/l, 1 PixelData
  (fffe,e000) pi (no value available)                     #   0, 1 Item
  (fffe,e000) pi 00\00\00\0c\6a\50\20\20\0d\0a\87\0a\00\00\00\14\66\74\79\70\6a\70... # 45422, 1 Item
(fffe,e0dd) na (SequenceDelimitationItem)               #   0, 0 SequenceDelimitationItem

Your source code contains some lines that should have created the offset table, but it obviously isn't there.

This article in the forum describes the second problem: in DICOM only the JPEG 2000 codestream, and not the full JP2 file must be embedded in the pixel sequence. A JPEG 2000 code stream always starts with the byte sequence FF 4F, and you can see that this is not the case with your byte stream, where this marker is at byte offset 0x55. So there is a JP2 header in front of that marker, which is not permitted in DICOM. Our 3.6.1 snapshot version of DCMJP2K has code that will skip such a header by looking for the FF 4F marker, and just print a warning, but earlier versions will report an error.

PostPosted: Tue, 2015-09-15, 22:01 

Joined: Thu, 2012-10-25, 07:18
Posts: 4
Thank you for this solution. I now ensure the data I use begins at the JPEG 2000 codestream by searching for:

const std::string jp2k_data("FF4F");

(And ends at FFD9.) I then insert the offset table to the pixel sequence:

DcmPixelItem *offsetTable   = new DcmPixelItem(DcmTag(DCM_Item, EVR_OB));
if (offsetTable != NULL)
   cond   = pixelSequence->insert(offsetTable); // etc

And store the compressed frame. Choose representation allows me to decompress, and I access the uncompressed data with findAndGetUint8Array. Thank you for the help.

Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC + 1 hour

Who is online

Users browsing this forum: No registered users and 1 guest

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group