compress image in memory?

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
markw
Posts: 84
Joined: Mon, 2005-01-17, 01:08

compress image in memory?

#1 Post by markw »

Hi,

Is it possible to open a DcmFileFormat object, then compress it in memory, then send it? I'm looking at store scu, and am trying something like:

Code: Select all

OFCondition cond = pDataset->chooseRepresentation(EXS_JPEGProcess14SV1TransferSyntax, &dcmRepresentationParameter);
if (cond.bad()) {
    return false;
}

// Check if everything went well
if (!pDataset->canWriteXfer(EXS_JPEGProcess14SV1TransferSyntax)) {
    return false;
}

// is the image compressed here?
I established a connection with another device using EXS_JPEGProcess14SV1TransferSyntax, so I want to open the uncompressed files, compress in memory, then send.

Thanks

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

#2 Post by Marco Eichelberg »

Yes, this is certainly possible. Make sure you have registered the compression codecs, and don't forget to implement code that handles those cases where the image cannot be compressed with the desired transfer syntax (e.g. because of bit depth, color model or the like).

markw
Posts: 84
Joined: Mon, 2005-01-17, 01:08

#3 Post by markw »

Hi Marco,

When does the compression actually take place, when pDataset->chooseRepresentation() is called? I'm trying to figure out how I can check if the dataset has actually been compressed in memory or not (writing it to disk is one way to check, but I thought the call to saveFile() might actually be the point when the compression takes place....)

Thanks

markw
Posts: 84
Joined: Mon, 2005-01-17, 01:08

#4 Post by markw »

Hi Marco,

I looked some more into storscu, I don't see how I can compress in memory and 'trick' storescu into sending the compressed file. There is a call in the application as:

Code: Select all

/* finally conduct transmission of data */
    cond = DIMSE_storeUser(assoc, presId, &req,
        NULL, dcmff.getDataset(), progressCallback, NULL,
        opt_blockMode, opt_dimse_timeout,
        &rsp, &statusDetail, NULL, DU_fileSize(fname));
The last parameter is reading the size of the original image from disk to get the number of bytes to transfer - but that won't be accurate if I compressed the dataset in memory beforehand - any way around this?

Thanks

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

#5 Post by Marco Eichelberg »

This is some very old part of the code, but if I remember correctly, the file size does not have any relevance. It is passed to the callback function and allows the callback to implement some kind of progress indicator on the GUI. I am quite sure that the C-STORE protocol (and implementation) do not need to know the size of the dataset in advance.

markw
Posts: 84
Joined: Mon, 2005-01-17, 01:08

#6 Post by markw »

Ok fair enough, I am still doubting that compression has taken place though - there doesn't seem to be any way for me to actually check that compression did take place in memory, so I tried transfering 100 1mb images with compression on and off, and there seems to be no difference in transfer time. Again, this is all I'm doing to compress the DcmFileFormat object in memory:

Code: Select all

DcmFileFormat dcm;
dcm.loadFile("whatever.dcm");
DcmDataset* pDataset = dcm.getDataset();
OFCondition cond = pDataset->chooseRepresentation(EXS_JPEGProcess14SV1TransferSyntax, &dcmRepresentationParameter); 
if (cond.bad()) { 
    return false; 
} 

// Check if everything went well 
if (!pDataset->canWriteXfer(EXS_JPEGProcess14SV1TransferSyntax)) { 
    return false; 
} 

// Now the original dcm object is compressed in memory?
On the other hand, if after the above code I call saveFile(), I can actually see the new file written compressed to disk. I can reload it then send the compressed image, and here I will see a difference in transfer speeds for 100 images. I just get the feeling that compression on the in memory object does not take place...

Thanks for any suggestions,
Mark

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

#7 Post by Marco Eichelberg »

Check the transfer syntax UID associated with the presentation context ID you pass to DIMSE_storeUser (parameter presId). This should refer to a compressed presentation context. You might also want to test your application with storescp --prefer-lossless --bit-preserving as a receiver - in this mode storescp will store the objects in "bit preserving" mode as they are received over the network connection. It should be fairly trivial to see if the files are compressed or not. Also using the various debug options of the code might help.

markw
Posts: 84
Joined: Mon, 2005-01-17, 01:08

#8 Post by markw »

Hi Marco,

I used the following command line options with storescp as you suggested:

>storescp.exe -v -d +B +xs

In a storescu application, I compress my file like:

Code: Select all

DcmDataset* dataSet   = _dcmff.getDataset();
DcmMetaInfo* metaInfo = _dcmff.getMetaInfo();

OFCondition cond = dataSet->chooseRepresentation(EXS_JPEGProcess14SV1TransferSyntax, DJ_RPLossless());
if (cond.bad()) {
    cout << "error" << endl;
    return cond;
}

// check if everything went well
if (dataSet->canWriteXfer(EXS_JPEGProcess14SV1TransferSyntax)) {
    // force the meta-header UIDs to be re-generated when storing the file 
    // since the UIDs in the data set may have changed 
    delete metaInfo->remove(DCM_MediaStorageSOPClassUID);
    delete metaInfo->remove(DCM_MediaStorageSOPInstanceUID);

    ...
 
    // dataSet should be compressed in-memory now, store to server.
    DIMSE_storeUser(dataSet);
}
storescp saves the files compressed (120k), while turning compression off gives me files of size (180k), so I suppose it worked, the compression really did take place in-memory.

If you have a free moment, can you verify if what I did to test that the dataset really is getting compressed in-memory was correct?

Thank you,
Mark

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

#9 Post by Marco Eichelberg »

Your code is correct as far as I can say. chooseRepresentation() is the method that actually triggers the compression codec, and a successful completion of this method (EC_Normal return code) means that a compressed version of the object is now available in memory. canWriteXfer() only checks if the compressed "representation" (=version of the object) already exists in memory and DIMSE_storeUser will not attempt to compress anything - the compressed representation exists or the transfer fails, given that a compressed presentation context is used for the transfer, which is easy to verify using storescp's debug output.

Post Reply

Who is online

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