I write my own Store SCU, which operates only on memory located datasets and recently I ecnoutered a problem while trying to use compressed transfer syntaxes, i.e. the JPEG ones.
Here's the code that causes the problem:
Code: Select all
DcmDataset * dcmDataset = new DcmDataset();
dcmDataset->putAndInsertUint16( DCM_FileMetaInformationVersion, 0x0001 );
dcmDataset->putAndInsertString( DCM_SOPClassUID, UID_SecondaryCaptureImageStorage );
dcmDataset->putAndInsertString( DCM_SOPInstanceUID, dcmGenerateUniqueIdentifier( uid, SITE_INSTANCE_UID_ROOT ) );
dcmDataset->putAndInsertString( DCM_PhotometricInterpretation, "RGB" );
dcmDataset->putAndInsertUint16( DCM_SamplesPerPixel, 3 );
dcmDataset->putAndInsertString( DCM_NumberOfFrames, "1" );
dcmDataset->putAndInsertUint16( DCM_BitsAllocated, 8 );
dcmDataset->putAndInsertUint16( DCM_BitsStored, 7 );
dcmDataset->putAndInsertUint16( DCM_HighBit, 7 );
dcmDataset->putAndInsertUint16( DCM_PixelRepresentation, 0 );
dcmDataset->putAndInsertUint16( DCM_PlanarConfiguration, 0 );
dcmDataset->putAndInsertUint16( DCM_SmallestImagePixelValue, 0 );
dcmDataset->putAndInsertUint16( DCM_LargestImagePixelValue, 255 );
dcmDataset->putAndInsertUint16( DCM_Rows, image.height() );
dcmDataset->putAndInsertUint16( DCM_Columns, image.width() );
unsigned char * data = new unsigned char [ image.height() * image.width() * 3 ];
// Processing image pixels.
// ...
dcmDataset->putAndInsertUint8Array(
DCM_PixelData, data, image.height() * image.width() * 3
);
DJ_RPLossy rp_lossy;
DJEncoderRegistration::registerCodecs();
if ( dcmDataset->chooseRepresentation( EXS_JPEGProcess1TransferSyntax, & rplossy ).bad() ) {
// Handle error.
}
if ( ! dcmDataset->canWriteXfer( EXS_JPEGProcess1TransferSyntax ) ) {
// Handle error.
}
I used debugger to find out what's wrong and stepped into the method. It appears that the `DcmImage::Init()' method (which is called when creating temporary object) doesn't support RGB Photomoetric Interpretation. Why is that?
The full call stack is as follows:
Code: Select all
theapp.exe!DicomImage::Init() Line 197 C++
theapp.exe!DicomImage::DicomImage(DcmObject * object=0x023dd218, E_TransferSyntax xfer=EXS_LittleEndianImplicit, const unsigned long flags=0, const unsigned long fstart=0, const unsigned long fcount=0) Line 105 C++
theapp.exe!DJCodecEncoder::encodeColorImage(bool YBRmode=false, DcmItem * dataset=0x023dd218, const DcmRepresentationParameter * toRepParam=0x0012d81c, DcmPixelSequence * & pixSeq=0x00000000, const DJCodecParameter * cp=0x023dd910, double & compressionRatio=0.00000000000000000) Line 286 + 0x36 bytes C++
theapp.exe!DJCodecEncoder::encode(const unsigned short * __formal=0x02ed0040, const unsigned short * __formal=0x02ed0040, const DcmRepresentationParameter * toRepParam=0x0012d81c, DcmPixelSequence * & pixSeq=0x00000000, const DcmCodecParameter * cp=0x023dd910, DcmStack & objStack={...}) Line 155 + 0x27 bytes C++
theapp.exe!DcmCodecList::encode(E_TransferSyntax fromRepType=EXS_LittleEndianExplicit, const unsigned short * pixelData=0x02ed0040, const unsigned long length=2805000, E_TransferSyntax toRepType=EXS_JPEGProcess1TransferSyntax, const DcmRepresentationParameter * toRepParam=0x0012d81c, DcmPixelSequence * & toPixSeq=0x00000000, DcmStack & pixelStack={...}) Line 449 + 0x43 bytes C++
theapp.exe!DcmPixelData::encode(const DcmXfer & fromType={...}, const DcmRepresentationParameter * fromParam=0x00000000, DcmPixelSequence * fromPixSeq=0x00000000, const DcmXfer & toType={...}, const DcmRepresentationParameter * toParam=0x0012d81c, DcmStack & pixelStack={...}) Line 384 + 0x2f bytes C++
theapp.exe!DcmPixelData::chooseRepresentation(E_TransferSyntax repType=EXS_JPEGProcess1TransferSyntax, const DcmRepresentationParameter * repParam=0x0012d81c, DcmStack & pixelStack={...}) Line 294 + 0x31 bytes C++
theapp.exe!DcmDataset::chooseRepresentation(E_TransferSyntax repType=EXS_JPEGProcess1TransferSyntax, const DcmRepresentationParameter * repParam=0x0012d81c) Line 528 + 0x2b bytes C++