Does DCMTK support Ultrasound Multiframe (RLE Lossless)?

All other questions regarding DCMTK

Moderator: Moderator Team

Message
Author
Niels Dekker
Posts: 40
Joined: Thu, 2005-05-26, 17:11
Location: Leiden (work), Amsterdam (home)
Contact:

Does DCMTK support Ultrasound Multiframe (RLE Lossless)?

#1 Post by Niels Dekker »

My C++ function "TryToReadDicomFile" uses the DCTKM class DicomImage to get data from a DICOM file, but it fails if the DICOM file is an Ultrasound Multiframe image, having RLE Lossless compression. Does DCMTK support reading this file format?

Code: Select all

// My function... fails on Ultrasound/RLE!
bool TryToReadDicomFile(const char myFilename[])
{
    DicomImage myDicomImage(myFilename);
    const void * myData = myDicomImage.getOutputData();

    if ( myData == NULL )
    {
        // Unfortunately, this happens for my Ultrasound/RLE images.
        return false;
    }
    else
    {
        // While other kinds of DICOM images are read successfully!
        return true;
    }
}
I did DcmRLEDecoderRegistration::registerCodecs() before calling TryToReadDicomFile.

The images TryToReadDicomFile couldn't read are all Intravascular Ultrasound DICOM files. They have the following header image information:

SOP Class UID: "1.2.840.10008.5.1.4.1.1.3.1"
Transfer Syntax UID: "1.2.840.10008.1.2.5"
Photometric Interpretation: "PALETTE COLOR"
Bits Allocated: 8
Bits Stored: 8
Lossy Image Compression: "00"

Your help is appreciated!

Niels

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 »

You also need to register support for color images by including "diregist.h" in your application (see source code example in DCMTK's documentation).

Niels Dekker
Posts: 40
Joined: Thu, 2005-05-26, 17:11
Location: Leiden (work), Amsterdam (home)
Contact:

#3 Post by Niels Dekker »

Thanks for your reply. Actually I did #include "diregist.h", but still my application can't read those Ultrasound DICOM files. Please let me know if you have any more suggestions... Here's my application. It was compiled by MSVC++ 7.1 on Win XP SP2:

Code: Select all

#include <cstdlib>
#include <cstdio>

#include "dcdatset.h"
#include "dcfilefo.h"
#include "dcmimage.h"
#include "dcfilefo.h"
#include "dcpixel.h"
#include "dcdeftag.h"
#include "dcvrus.h"
#include "dcvris.h"
#include "dipalimg.h"

#include "diregist.h"
#include "djdecode.h"
#include "dcrledrg.h"

#pragma comment (lib, "dcmjpeg.lib")
#pragma comment (lib, "ijg8.lib")
#pragma comment (lib, "ijg12.lib")
#pragma comment (lib, "ijg16.lib")
#pragma comment (lib, "zlib.lib")
#pragma comment (lib, "dcmimgle.lib")
#pragma comment (lib, "ofstd.lib")
#pragma comment (lib, "dcmdata.lib")
#pragma comment (lib, "dcmimage.lib")
#pragma comment (lib, "netapi32.lib")
#pragma comment (lib, "wsock32.lib")

class DicomCodecRegistration
{
public:
    DicomCodecRegistration(void)
    {
        DcmRLEDecoderRegistration::registerCodecs();
        DJDecoderRegistration::registerCodecs();
    }
    ~DicomCodecRegistration(void)
    {
        DJDecoderRegistration::cleanup();
        DcmRLEDecoderRegistration::cleanup();
    }
};

bool TryToReadDicomFile(const char myFilename[])
{
    DicomImage myDicomImage(myFilename);

    const void * myData = myDicomImage.getOutputData();

    if ( myData == NULL )
    {
        // Unfortunately, this happens for my Ultrasound/RLE images.
        return false;
    }
    else
    {
        // While other kinds of DICOM images are read successfully!
        return true;
    }
}


int main(int argc, char *argv[])
{
    DicomCodecRegistration myDicomCodecRegistration;
    if (argc > 1)
    {
        std::printf("DICOM input file: ");
        std::puts(argv[1]);
        if ( TryToReadDicomFile( argv[1] ) )
        {
            std::puts("Succeeded!");
            return EXIT_SUCCESS;
        }
        else
        {
            std::puts("Failed!");
            return EXIT_FAILURE;
        }
    }
    return EXIT_SUCCESS;
}

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

#4 Post by Jörg Riesmeier »

What is the return value of myDicomImage.getStatus()?

You should also enable the verbose/debug mode (see example application "dcm2pnm").
Btw, are you able to process this particular US image with dcm2pnm?

Niels Dekker
Posts: 40
Joined: Thu, 2005-05-26, 17:11
Location: Leiden (work), Amsterdam (home)
Contact:

#5 Post by Niels Dekker »

myDicomImage.getStatus() returns 0 when I read a DICOM file successfully. But for my US files it returns 4 (EIS_InvalidValue).

I added the following code to my app, I guess that's what you mean by enabling the verbose/debug mode...

Code: Select all

DicomImageClass::setDebugLevel(DicomImageClass::DL_NoMessages
  | DicomImageClass::DL_Errors
  | DicomImageClass::DL_Warnings
  | DicomImageClass::DL_Informationals
  | DicomImageClass::DL_DebugMessages);
Now my program says the following, when trying to read a US file:
ERROR: cannot change to unencapsulated representation for pixel data !
INFO: detach pixel data
Does this mean that this kind of images is not supported by DCMTK?

Thanks for your advise to try "dcm2pnm". I haven't compiled it yet, but I'll try to do so, if necessary...

Niels Dekker
Posts: 40
Joined: Thu, 2005-05-26, 17:11
Location: Leiden (work), Amsterdam (home)
Contact:

#6 Post by Niels Dekker »

My collegues helped me compiling "dcm2pnm". Unfortunately it says:
D:\dcmtk\dcmimage\apps\Debug>dcm2pnm.exe MyUltrasound.dcm
ERROR: cannot change to unencapsulated representation for pixel data !
$dcmtk: dcmj2pnm v3.5.2 2002-12-23 $

dcmj2pnm: Convert DICOM images to PGM, PPM, BMP, TIFF or JPEG
error: Invalid data value
Any more suggestions, please?

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

#7 Post by Jörg Riesmeier »

Are you sure that your US image is correct? You can send the file to dicom/at/offis/dot/de if you want.

Btw, there are also precompiled binaries of our DCMTK tools on the website (incl. dcm2pnm).

Niels Dekker
Posts: 40
Joined: Thu, 2005-05-26, 17:11
Location: Leiden (work), Amsterdam (home)
Contact:

#8 Post by Niels Dekker »

Thanks again, Jörg. Yes, I think our US images are correct. The images are directly from the imager (Intravascular Ultrasound). They are displayed correctly by viewers like IrfanView (including its plugins) and the Sante Dicom Viewer. I'm not sure if I'm allowed to send you one, though. I'd have to ask my collegues at the medical center, here in Leiden, NL.

Have a nice weekend!

Niels

Niels Dekker
Posts: 40
Joined: Thu, 2005-05-26, 17:11
Location: Leiden (work), Amsterdam (home)
Contact:

#9 Post by Niels Dekker »

Hi Jörg,

Last Monday I sent you an Ultrasound image file from the Leiden University Medical Center (LUMC). Did you get this e-mail? And were you able to get the image file out of the password protected ZIP file?

Kind regards,

Niels

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

#10 Post by Jörg Riesmeier »

We checked the image and it seems that the Run Length Encoding (RLE) of the pixel data is corrupted. However, we need further investigation to verify this ...

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

#11 Post by Marco Eichelberg »

To be more precise, the decompressor refuses the image because some of the RLE fragments decompress into insufficient data to fill a frame (frame 1 and 3 of the sample you provided are short by a single byte, but that is sufficient in this case). So according to our analysis the multiframe images are defective. It is another question of course whether it would be possible to add a workaround to the RLE decoder that would silently accept such images. This could certainly be done but requires a few modifications deeply inside the RLE codec.

Niels Dekker
Posts: 40
Joined: Thu, 2005-05-26, 17:11
Location: Leiden (work), Amsterdam (home)
Contact:

#12 Post by Niels Dekker »

Sounds like I need some kind of workaround... Can you please tell me how to modify my copy of DCMTK, so that it would accept the US file that I sent you? It seems like I got the same kind of problems for images from various Intravascular Ultrasound imagers. So in the end it might be worth updating the official DCMTK release. But at this moment, I would be very happy with some "quick fix"!

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

#13 Post by Marco Eichelberg »

The modification would affect DcmRLECodecDecoder::decode() in dcmdata/libsrc/dcrleccd.cc, however, this is some fairly complex code and I don't have the time right now to spend a couple of hours on developing a workaround. I will put this on our to-do-list, but cannot promise more at the moment.

j.eggermont
Posts: 13
Joined: Thu, 2010-03-25, 13:04

#14 Post by j.eggermont »

For the last few years we've used a snapshot version of DCMTK 3.5.4 in which we "patched" the RLE decoder so that we could correctly read the incorrectly RLE encoded DICOM files.

Recently we have been looking at the latest 3.5.5 snapshots of DCMTK because of the ability to decode only a limited number of frames at a time. This is an important new feature for us since we sometimes need to be able to decode up to 4000+ 512x512 IVUS frames.

However we in order to read the incorrect RLE encoded files we needed to "patch" the decodeFrame(...) function.

In the decodeFrame(...) function we changed

Code: Select all

// copy the decoded stuff over to the buffer here...
// make sure the RLE decoder has produced the right amount of data
if (rledecoder.size() != bytesPerStripe)
{
             // error: RLE decoder is finished but has produced insufficient data for this stripe
            return EC_CannotChangeRepresentation; 
}

into:

Code: Select all

// copy the decoded stuff over to the buffer here...
// make sure the RLE decoder has produced the right amount of data
if (rledecoder.size() != bytesPerStripe)
{
	// error: RLE decoder is finished but has produced insufficient data for this stripe
			
	// BEGIN RLE MISSING PIXELS PATCH
	if(lastStripe && (rledecoder.size() < bytesPerStripe))
	{
		if(result==EC_StreamNotifyClient) // stream ended premature ?
		{
			result = EC_Normal;
		}
	}
	else // orginal code
		return EC_CannotChangeRepresentation; 
	// END RLE MISSING PIXELS PATCH
}
and changed the for-loop at the end of the function from:

Code: Select all

for (pixel = 0; pixel < bytesPerStripe; ++pixel)
{
	*pixelPointer = *outputBuffer++;
	pixelPointer += offsetBetweenSamples;
}
to:

Code: Select all

// BEGIN RLE MISSING PIXELS PATCH
//copy the pixel data that was decoded
for (pixel = 0; pixel < rledecoder.size(); ++pixel)
{
	*pixelPointer = *outputBuffer++;
	pixelPointer += offsetBetweenSamples;
}
//and fill the remainder of the image with copies of the last decoded pixel
Uint8 lastPixelValue=*(outputBuffer-1);
for (pixel = rledecoder.size(); pixel < bytesPerStripe; ++pixel)
{
	*pixelPointer = lastPixelValue;
	pixelPointer += offsetBetweenSamples;
}
// END RLE MISSING PIXELS PATCH
}
Would be possible for you to change the DcmRLECodecDecoder in a similar manner ?

It would be a great help for us if at least the pixels that were decoded can be retrieved from the DicomImage even if the status of the image is not EC_Normal.

This would make it possible for us to use the standard DCMTK snapshot instead of having to patch it locally.
Dr. J. Eggermont, PhD
Division of Image Processing
Department of Radiology
Leiden University Medical Center

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

#15 Post by Jörg Riesmeier »

Thank you for the patch. We've added a note to the existing item on our to-do list. We'll fix this issue as time permits ...

Post Reply

Who is online

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