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().