diff --git a/src/src/IO/DICOM/DICOMPixelDataHelper.cpp b/src/src/IO/DICOM/DICOMPixelDataHelper.cpp index 5ca003f..9625599 100644 --- a/src/src/IO/DICOM/DICOMPixelDataHelper.cpp +++ b/src/src/IO/DICOM/DICOMPixelDataHelper.cpp @@ -61,10 +61,10 @@ void DICOMPixelDataHelper::GetPixelData(const char * path, void *data, unsigned DcmFileFormat *fileFormat = new DcmFileFormat();//读取文件获取传输语法 if (fileFormat->loadFile(path).good()) { DcmDataset *dset = fileFormat->getDataset(); - DicomImage* dcmImage = new DicomImage(fileFormat, dset->getOriginalXfer(),CIF_MayDetachPixelData); - const DiPixel* pixelData = dcmImage->getInterData();//rescaled + DicomImage dcmImage(fileFormat, dset->getOriginalXfer(), CIF_MayDetachPixelData); + const DiPixel *pixelData = dcmImage.getInterData();//rescaled unsigned long dataBits = 1; - switch (pixelData->getRepresentation()){ + switch (pixelData->getRepresentation()) { case EPR_Uint8: case EPR_Sint8: break; @@ -77,12 +77,10 @@ void DICOMPixelDataHelper::GetPixelData(const char * path, void *data, unsigned dataBits = 4; break; } - - const void * dd = pixelData->getData(); - length = pixelData->getCount() ; - length = length*dataBits; - memcpy(data,dd, length); - delete dcmImage; + const void *dd = pixelData->getData(); + length = pixelData->getCount(); + length = length * dataBits; + memcpy(data, dd, length); } else{ length=-1; } @@ -100,8 +98,8 @@ void convertAndRescale(const void* input, void* output, double slope, double int } -void* DICOMPixelDataHelper::GetPixelDataFloat(const char *path, unsigned long &length) { - void* data = nullptr; +void DICOMPixelDataHelper::GetPixelDataFloat(const char *path, void *data, unsigned long &length) { + void* temp = nullptr; DcmFileFormat *fileFormat = new DcmFileFormat(); if (fileFormat->loadFile(path).good()) { DcmDataset *dataset = fileFormat->getDataset(); @@ -109,36 +107,51 @@ void* DICOMPixelDataHelper::GetPixelDataFloat(const char *path, unsigned long &l const DiPixel* pixelData = dcmImage.getInterData();//no rescaled length = pixelData->getCount(); const void* pData = pixelData->getData(); - data = new float [length]; - double slope= 1.0; + double slope = 1.0; dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1053), slope); - double intercept= 0.0; + double intercept = 0.0; dataset->findAndGetFloat64(DcmTagKey(0x0028, 0x1052), intercept); switch (pixelData->getRepresentation()){ case EPR_Uint8: - convertAndRescale(pData,data,slope,intercept,length); + convertAndRescale(pData, data, slope, intercept, length); break; case EPR_Sint8: - convertAndRescale(pData,data,slope,intercept,length); + convertAndRescale(pData, data, slope, intercept, length); break; case EPR_Uint16: - convertAndRescale(pData,data,slope,intercept,length); + convertAndRescale(pData, data, slope, intercept, length); break; case EPR_Sint16: - convertAndRescale(pData,data,slope,intercept,length); + convertAndRescale(pData, data, slope, intercept, length); break; case EPR_Uint32: - convertAndRescale(pData,data,slope,intercept,length); + convertAndRescale(pData, data, slope, intercept, length); break; case EPR_Sint32: - convertAndRescale(pData,data,slope,intercept,length); + convertAndRescale(pData, data, slope, intercept, length); break; } + length = length * sizeof(float); + } else{ + length=-1; + } + delete fileFormat; +} + +void DICOMPixelDataHelper::GetRGBPixelData(const char *path, void *data, unsigned long &length) { + DcmFileFormat *fileFormat = new DcmFileFormat();//读取文件获取传输语法 + if (fileFormat->loadFile(path).good()) { + DcmDataset *dset = fileFormat->getDataset(); + DicomImage dcmImage(fileFormat, dset->getOriginalXfer(), CIF_MayDetachPixelData); + dcmImage.hideAllOverlays(); + length = dcmImage.getOutputDataSize(8); + const void *dd = dcmImage.getOutputData(8); + memcpy(data, dd, length); + dcmImage.deleteOutputData(); } else{ length=-1; } delete fileFormat; - return data; } void DICOMPixelDataHelper::GetOverlayData(const char *path, void *data, diff --git a/src/src/IO/DICOM/DICOMPixelDataHelper.h b/src/src/IO/DICOM/DICOMPixelDataHelper.h index 1eebcb2..9adfc6b 100644 --- a/src/src/IO/DICOM/DICOMPixelDataHelper.h +++ b/src/src/IO/DICOM/DICOMPixelDataHelper.h @@ -7,6 +7,9 @@ class ExtendMedicalImageProperties; +/** + * DICOM file Pixel Data read helper + */ class DICOMPixelDataHelper { public: DICOMPixelDataHelper() = default; @@ -15,13 +18,42 @@ public: } static void GetThumbnailData(ExtendMedicalImageProperties *property, unsigned char* data, unsigned long& length); - static void GetPixelData(const char * path, void* data,unsigned long& length); - static void* GetPixelDataFloat(const char * path,unsigned long& length); + /** + * Get Pixel Data with Rescaled, result is calculate as integer, and arrange as integer. + * @param path dcm file absolute path + * @param data output data buffer pointer + * @param length output data length + */ + static void GetPixelData(const char * path, void* data, unsigned long& length); + + /** + * Get Pixel Data with Rescaled, result is calculate as Float, and arrange as Float. + * @param path dcm file absolute path + * @param data output data buffer pointer + * @param length output data length + */ + static void GetPixelDataFloat(const char * path, void* data, unsigned long& length); + + /** + * Get colorful Pixel Data as three component R,G,B color value. + * @param path dcm file absolute path + * @param data output data buffer pointer + * @param length output data length + */ + static void GetRGBPixelData(const char * path, void* data, unsigned long& length); + + static void GetOverlayData(const char * path, void* data, unsigned int& width, unsigned int& height,unsigned int plane = 0); + /** + * Init decompress Codecs, must be called before other method. + */ static void InitCodecs(); + /** + * Finalize decompress Codecs, must be called after other method have done. + */ static void FinalizeCodecs(); }; diff --git a/src/src/IO/DICOM/ExtendMedicalImageProperties.cpp b/src/src/IO/DICOM/ExtendMedicalImageProperties.cpp index 204c150..38b69b8 100644 --- a/src/src/IO/DICOM/ExtendMedicalImageProperties.cpp +++ b/src/src/IO/DICOM/ExtendMedicalImageProperties.cpp @@ -98,11 +98,3 @@ void ExtendMedicalImageProperties::GenerateUniqueID() { this->SetUniqueID(uniqueID.c_str()); } -bool ExtendMedicalImageProperties::RescaledImageDataIsUnsignedChar() { - bool charData = BitsAllocated == 8; - bool noScale = ((int)(this->RescaleOffset) == 0) && ((int)(this->RescaleSlope) == 1); - bool unSign = (this->PixelRepresentation == 0); - bool color = SamplePerPixel == 3; - return (color || (charData && unSign && noScale)); -} - diff --git a/src/src/IO/DICOM/vtkDICOMImageReader2.cpp b/src/src/IO/DICOM/vtkDICOMImageReader2.cpp index b625aed..2b27522 100644 --- a/src/src/IO/DICOM/vtkDICOMImageReader2.cpp +++ b/src/src/IO/DICOM/vtkDICOMImageReader2.cpp @@ -93,37 +93,33 @@ void vtkDICOMImageReader2::ExecuteDataWithInformation(vtkDataObject *output, vtkErrorMacro(<< "No memory allocated for image data!"); return; } + + // init codes to support compressed file + DICOMPixelDataHelper::InitCodecs(); + for (int i = 0; i < properties->GetFileNames().size(); ++i) { - const std::string& path = properties->GetFileNames()[i]; - if (this->DataScalarType == VTK_FLOAT) - { - void *imgData = nullptr; + const std::string &path = properties->GetFileNames()[i]; - unsigned long imageDataLength; + unsigned long imageDataLength; + + if (this->DataScalarType == VTK_FLOAT) { + + DICOMPixelDataHelper::GetPixelDataFloat(path.c_str(), buffer, imageDataLength); + + } else if (NumberOfScalarComponents > 1) { + + DICOMPixelDataHelper::GetRGBPixelData(path.c_str(), buffer, imageDataLength); + + } else { + + DICOMPixelDataHelper::GetPixelData(path.c_str(), buffer, imageDataLength); - imgData = DICOMPixelDataHelper::GetPixelDataFloat(path.c_str(),imageDataLength); - if(imgData){ - //calc size of float - imageDataLength = imageDataLength * sizeof(float); - unsigned char *b = (unsigned char *) buffer; - unsigned char *iData = (unsigned char *) imgData; - memcpy(b, imgData, imageDataLength); - buffer = ((char*) buffer) + imageDataLength; - } - else{ - vtkErrorMacro(<< "Can't read data from path:"<