How to do Per frame jpeg2000 encoding?

Questions regarding the DCMJP2K library, a DCMTK add-on that implements support for JPEG 2000 compression (lossy and lossless) in DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
DGyuraki
Posts: 2
Joined: Mon, 2024-06-24, 08:52

How to do Per frame jpeg2000 encoding?

#1 Post by DGyuraki »

Hello.

I'm trying to create a way to use less ram while exporting dicoms to jpeg2000 format from our software . My idea is to use a frame by frame way to encode each. Then combine them together rather than doing all at once.

First I only partialy load the dicom file and only latter load in the pixeldata.

Code: Select all

result = m_dcmff->loadFile( fname, inputXfer, EGL_noChange, 4096 );
I want to do it on a frame by frame basis.

Code: Select all

OFCondition errors = elem->getUncompressedFrame(dataset, frameNo, startFragment, buffer, bufSize, decompressedColorModel, NULL);
My main problem is here while it seems to have a way to directly add in pixeldata.From the code it doesn't actually seems to use it and will just load in everything anyway and do all the frames at once in the d2codece part. While I understand that if I modify the d2codece part and add an extra flag to the part where it gets loaded in with the DicomImage.This could be somewhat mitigated but even than I would have to load in everything together anyway at least once.Also without heavily modifying d2codece part by storing the frame in a temporary way as soon as the frame has been compressed the ram usage would be the same just with a different usage curvature.

Code: Select all

l_error = DcmCodecList::encode(EXS_Unknown, buffer,bufSize,outXfer,repParam,pixSeqOut,pixelStack);
Is there anyway to actually make this work directly on the pixelData which is in the buffer and not on the dataset inside the stack which get passed as pixelstack?

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

Re: How to do Per frame jpeg2000 encoding?

#2 Post by Marco Eichelberg »

We are actually talking about JPEG 2000 decoding here, which is good, because per-frame encoding is not supported in DCMTK, while per-frame decoding is.

Loading the file with DcmFileFormat::loadFile() is a "lazy" operation that will leave the compressed pixel data in the file until it is accessed.
First let's get a pointer to the pixel data element and use that to decode individual frames:

Code: Select all

OFCondition cond;
DcmElement *elem = NULL;
cond = dataset->findAndGetElement(DCM_PixelData, elem);
if (cond.bad()) return cond;
Next you determine the number of frames, the size of each frame (in bytes), and allocate a buffer

Code: Select all

Uint32 frameSize = 0;
Sint32 numberOfFrames = 0;
cond = getUncompressedFrameSize(dataset, frameSize, OFFalse);
if (cond.bad()) return cond;
cond = dataset->findAndGetSint32(DCM_NumberOfFrames, numberOfFrames);
if (cond.bad()) return cond;
if (numberOfFrames < 1) numberOfFrames = 1;
char *buffer = new char[frameSize];
Finally, you access each frame in a loop. The getUncompressedFrame() method will temporarily load the compressed pixel data belonging to one frame, decompress it, copy it into the output buffer, and then delete the local copy.
This makes sure that never more than one frame is in memory:

Code: Select all

Uint32 fragment = 0;
DcmFileCache cache;
OFString decompressedColorModel;
for (Uint32 i = 0; i < (Uint32)numberOfFrames; ++i)
{
  cond = elem->getUncompressedFrame(dataset, i, fragment, buffer, frameSize, decompressedColorModel, cache);
  if (cond.bad()) return cond;
  
  // now buffer contains one uncompressed frame of pixel data. 
}
Warning: Code is untested, but should show the principle.
Note that the color model for the decompressed frame will typically be different from the compressed color model in the case of color images. Since we're not modifying the source dataset, the color model of the decompressed frame is explicitly returned by getUncompressedFrame().

DGyuraki
Posts: 2
Joined: Mon, 2024-06-24, 08:52

Re: How to do Per frame jpeg2000 encoding?

#3 Post by DGyuraki »

Sorry but I'm a bit confussed what I'm trying to achive is to open a dicom files which has images in whatever format and convert them to jpeg2000. Isn't that the job of an encoder ? Since it will be the one to encode them in the jpeg2000 format from whatever they were originaly?

If I do what you suggest I understand that I would get the uncompressed pixel data but How could I then export this data as jpeg2000 without encoding it as such and then replacing or creating a new file to save it to.

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

Re: How to do Per frame jpeg2000 encoding?

#4 Post by Marco Eichelberg »

In this case I completely misunderstood your initial post, sorry. In order to convert DICOM images to JPEG 2000 files, you should use class DicomImage, which also allows you to perform those pre-processing steps that DICOM requires but that are not possible in JPEG 2000. Look at the implementation of the dcm2pnm/dcmj2pnm tool in DCMTK. This reads a DICOM image, and converts one selectable frame to BMP, PNG, PNM or JPEG. Essentially you need to replace the JPEG export by a JPEG 2000 export.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest