DcmPixelItem writing large buffer (from another file)

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
theonlylawislove
Posts: 34
Joined: Thu, 2014-07-17, 09:07

DcmPixelItem writing large buffer (from another file)

#1 Post by theonlylawislove »

I have code to create a MPEG/VideoEndo video dcm file (feel free to mention if that looks wrong) and it works. Here is the code.

Code: Select all


class CustomPixelData : DcmPixelItem
{
public:
	CustomPixelData(char const* file, const DcmTag &tag, const Uint32 len = 0) : DcmPixelItem(tag, len)
	{
		std::vector<char> fileBytes = ReadAllBytes(file);
		putUint8Array(OFreinterpret_cast(Uint8*, &fileBytes[0]), fileBytes.size());
	};
};


DcmFileFormat fileFormat;
DcmDataset *dataset = fileFormat.getDataset();

dataset->putAndInsertString(DCM_LossyImageCompression, "01");
dataset->putAndInsertString(DCM_PhotometricInterpretation, "YBR_PARTIAL_420");
dataset->putAndInsertUint16(DCM_SamplesPerPixel, 3);
dataset->putAndInsertUint16(DCM_BitsAllocated, 8);
dataset->putAndInsertUint16(DCM_BitsStored, 8);
dataset->putAndInsertUint16(DCM_HighBit, 7);
dataset->putAndInsertUint16(DCM_PlanarConfiguration, 0);
dataset->putAndInsertString(DCM_SOPClassUID, UID_VideoEndoscopicImageStorage);

DcmPixelSequence* pixelSequence = new DcmPixelSequence(DcmTag(DCM_PixelData, EVR_OB));

// add the table offset
DcmPixelItem *offsetTable = new DcmPixelItem(DcmTag(DCM_Item, EVR_OB));
pixelSequence->insert(offsetTable);

// create the compressed pixel data and add it to the sequence
CustomPixelData* compressedPixelData = new CustomPixelData("existing.mpg, DcmTag(DCM_Item, EVR_OB));
pixelSequence->insert((DcmPixelItem*)compressedPixelData);

DcmPixelData *pixelData = new DcmPixelData(DCM_PixelData);
pixelData->putOriginalRepresentation(EXS_MPEG2MainProfileAtMainLevel, NULL, pixelSequence);
dataset->insert(pixelData);

char uid[100];
dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT);
dataset->putAndInsertString(DCM_SOPInstanceUID, uid);
dcmGenerateUniqueIdentifier(uid, SITE_SERIES_UID_ROOT);
dataset->putAndInsertString(DCM_SeriesInstanceUID, uid);
dcmGenerateUniqueIdentifier(uid, SITE_STUDY_UID_ROOT);
dataset->putAndInsertString(DCM_StudyInstanceUID, uid);

fileFormat.saveFile(STRING_PTR_TO_CHAR(outputPtr), EXS_MPEG2MainProfileAtMainLevel, EET_UndefinedLength, EGL_recalcGL);

As you can see, I have to read the entire video into memory, before outputting it into another file. These videos can be very large, so ideally, I would like to read the existing mpg file into a buffer to write (on fileFormat.saveFile) to the output file on-the-fly. As you can see from the code, I began to subclass the DcmPixelItem to override some write methods to write the bytes manually, but I am having troubles figuring out how.

Any help would be appreciated. Thanks!

J. Riesmeier
DCMTK Developer
Posts: 2503
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: DcmPixelItem writing large buffer (from another file)

#2 Post by J. Riesmeier »

You should/could use DcmElement::createValueFromTempFile(). An example on how to use it can be found in the source code of dump2dcm:

Code: Select all

    /* create stream object for binary file */
    DcmInputFileStream fileStream(filename);
    ec = fileStream.status();
    if (ec.good())
    {
        /* NB: if size is odd file will be rejected */
        const size_t fileLen = OFStandard::getFileSize(filename);
        /* read element value from binary file (requires even length) */
        ec = elem->createValueFromTempFile(fileStream.newFactory(), fileLen, EBO_LittleEndian);
        if (ec.bad())
            OFLOG_ERROR(dump2dcmLogger, "cannot process binary data file: " << filename);
    } else {

[...]

theonlylawislove
Posts: 34
Joined: Thu, 2014-07-17, 09:07

Re: DcmPixelItem writing large buffer (from another file)

#3 Post by theonlylawislove »

I tried your code, and I am getting EC_IllegalCall, which after looking at the source code, seems to be because of file size is an odd number of bytes.

How should I fix this? Should I manually add 1 byte at the end of my original file? Should I just increase the file size sent to createValueFromTempFile to make it even?

J. Riesmeier
DCMTK Developer
Posts: 2503
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: DcmPixelItem writing large buffer (from another file)

#4 Post by J. Riesmeier »

I tried your code, and I am getting EC_IllegalCall, which after looking at the source code, seems to be because of file size is an odd number of bytes.
This is a known limitation that is documented both in the above cited source code snipped (see comments) as well as in the API documentation.
DICOM requires an even length for all element values, so does this function. So, you should make sure that the size of your file is even.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest