I'm a new user of DCMTK and I'm trying to load and register 2 sets of 512x512x508 slices of CT dicom images with the loader I provided below. My dicom data is jpeg compressed and the loader was designed accordingly. When I try to load the data with that loader, my PC with a RAM of 3.2GB turns out to be insufficient. The code cannot allocate enough memory for the data. I need two things at this point:
1) To obtain the jpeg uncompressed version of the data and save them into .dcm files. There seems to be just a line for uncompression:
Code: Select all
DJDecoderRegistration::registerCodecs();
2) To overcome the memory insufficiency problem, which stems from the loader. I couldn't deallocate the datatypes of DCMTK since I have just began dealing with them. delete methods do not work and I couldn't use the clear methods within different classes of DCMTK. Could anyone point me out how to free the memory through the steps within the loader below? If I don't free them step by step, memory allocation problem will remain.
Any kind of solution/suggestion will be appreciated. Thanks in advance.
Code: Select all
DICOMLoader::dicomReader ( char* firstFile, int modal, int numSlices, int loc1, int loc2, int numberPart )
{
DJDecoderRegistration::registerCodecs();
int currentSlice = 0;
long int numBits;
long int depth;
char* fileName = new char[255];
//converting char* firstFile to string fileNameStr
string fileNameStr ( firstFile );
int lengthOfFileName = fileNameStr.length();
int numberLength = loc2 - loc1 + 1;
string numberPartStr = fileNameStr.substr(loc1, numberLength);
string numberPartStrShort;
DcmFileFormat *dfile = new DcmFileFormat();
for ( currentSlice = 0; currentSlice < numSlices; currentSlice++ )
{
//this loop searches for the next file, in case file number of the next slice is not equal to (its antecedent's file number + 1)
while(1)
{
stringstream intToStr;
intToStr << numberPart;
numberPartStrShort = intToStr.str();
int numberLength2 = numberPartStrShort.length();
for(int i = 0 ; i < (numberLength-numberLength2); i++)
numberPartStrShort = "0" + numberPartStrShort;
//update fileName according to the current slice
fileNameStr.replace ( loc1, numberLength, numberPartStrShort );
//converting string fileNameStr to char* fileName
strcpy ( fileName, fileNameStr.c_str() );
OFCondition status = dfile->loadFile ( fileName );
numberPart++;
if(status.good())
{
//cout << fileName << endl;
break;
}
}
DcmDataset *ds = dfile->getDataset();
unsigned long opt_compatibilityMode = CIF_MayDetachPixelData | CIF_TakeOverExternalDataset;
E_TransferSyntax xfer = ds->getOriginalXfer();
DicomImage *di = new DicomImage ( dfile, xfer, opt_compatibilityMode, 0, 0);
imWidth = di->getWidth();
imHeight = di->getHeight();
numBits = di->getDepth(); //returns number of bits per sample
//determine the image depth according to the bit info
if ( numBits % 8 == 0 )
depth = numBits/8;
else
depth = ( numBits/8 ) + 1;
vtkImageData *image = vtkImageData::New();
if ( currentSlice == 0 )
{
switch ( depth )
{
case 1:
{
image -> SetScalarTypeToUnsignedChar();
break;
}
case 2:
{
image -> SetScalarType ( VTK_TYPE_UINT16 );
break;
}
case 3:
{
image -> SetScalarType ( VTK_TYPE_UINT32 );
break;
}
case 4:
{
image -> SetScalarType ( VTK_UNSIGNED_LONG );
break;
}
case 8:
{
image -> SetScalarType ( VTK_DOUBLE );
break;
}
default:
{
cout << "Invalid scalar type!" << endl;
}
}
}
const DiPixel *dmp = di -> getInterData ();
const void *pixelData = dmp -> getData();
Uint32 *castedPixelData = new Uint32(imWidth*imHeight);
castedPixelData = (Uint32*)pixelData;
image -> SetDimensions ( imWidth, imHeight, 1 );
image -> SetOrigin ( 0, 0, 0 );
image -> SetNumberOfScalarComponents ( 1 );
image -> AllocateScalars();
image -> Update();
Sint16* imagePointer = ( Sint16* ) image -> GetScalarPointer();
imagePointer = ( Sint16* )castedPixelData;
image -> Update();
//initialize variable when processing the first slice
if ( currentSlice == 0 )
{
double* spacing = NULL;
spacing = image->GetSpacing();
double* origin = NULL;
origin = image->GetOrigin();
int* dimension = NULL;
dimension = image->GetDimensions();
data_scalar->setInitials ( dimension[0], dimension[1], numSlices, spacing[0], spacing[1], spacing[2], origin[0], origin[1], origin[2] );
data_scalar->createData();
vtkData = data_scalar->getDataArray();
}
for(int m=0; m<imWidth*imHeight; m++)
vtkData->InsertNextValue ( imagePointer[m] + 1024 );
}
// clean up the registered codecs
DJDecoderRegistration::cleanup();
}