/*========================================================================= Program: DICOMParser Module: DICOMAppHelper.h Language: C++ Copyright (c) 2003 Matt Turek All rights reserved. See Copyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #ifndef __DICOM_APP_HELPER_H_ #define __DICOM_APP_HELPER_H_ #ifdef _MSC_VER #pragma warning(disable : 4514) #pragma warning(push, 3) #endif #include #include #include #include "DICOMCallback.h" #include "DICOMConfig.h" #include "DICOMTypes.h" namespace DICOMPARSER_NAMESPACE { class DICOMParser; // Function object for sorting strings struct ltstdstr { ltstdstr() {} bool operator()(const dicom_stl::string& s1, const dicom_stl::string& s2) const { return s1 < s2; } }; // Helper structure for DICOM elements struct DICOMTagInfo { doublebyte group; doublebyte element; DICOMParser::VRTypes datatype; const char* description; }; // Helper class use for ordering DICOM images based on different // (group, element) tags. class DICOM_EXPORT DICOMOrderingElements { public: DICOMOrderingElements() { // Default values to something "valid" SliceNumber = -1; SliceLocation = 0.0; ImagePositionPatient[0] = 0.0; ImagePositionPatient[1] = 0.0; ImagePositionPatient[2] = 0.0; ImageOrientationPatient[0] = 1.0; ImageOrientationPatient[1] = 0.0; ImageOrientationPatient[2] = 0.0; ImageOrientationPatient[3] = 0.0; ImageOrientationPatient[4] = 1.0; ImageOrientationPatient[5] = 0.0; } int SliceNumber; float SliceLocation; float ImagePositionPatient[3]; float ImageOrientationPatient[6]; }; class DICOMAppHelperImplementation; /** * \class DICOMAppHelper * \brief Class to interface an application to a DICOMParser * * DICOMAppHelper assists an application in communicating with a * DICOMParser. DICOMAppHelper registers a series of callbacks to the * DICOMParser which allows it to cache the information from a DICOM * file in a format that is appropriate for an application to * use. Once a DICOM file is read, an application can query the * DICOMAppHelper for the resolution, pixel size, and pixel data. * * If a DICOMParser scans more than one file, the DICOMAppHelper will * group filesnames by SeriesUID. This allows an application to pass * a series of DICOM files to the DICOMParser (which via the callback * mechanism allows the DICOMAppHelper to cache information) and then * query the DICOMAppHelper for the files that are from the same * series. The application can request the filenames for a particular * series to be sorted based on image number, slice location, or * patient position. This allows the DICOMAppHelper to assist an * application is collecting all the images from one series into a * volume. */ class DICOM_EXPORT DICOMAppHelper { public: /** Standard constructor */ DICOMAppHelper(); /** Standard destructor */ virtual ~DICOMAppHelper(); /** Callbacks that are registered with the DICOMParser. The * DICOMParser will call one of these callbacks whenever it * encounters a (group, element) that has an associated callback */ virtual void RescaleSlopeCallback(DICOMParser* parser, doublebyte group, doublebyte element, DICOMParser::VRTypes type, unsigned char* val, quadbyte len); virtual void ArrayCallback(DICOMParser* parser, doublebyte group, doublebyte element, DICOMParser::VRTypes type, unsigned char* val, quadbyte len); virtual void SliceNumberCallback(DICOMParser* parser, doublebyte group, doublebyte element, DICOMParser::VRTypes type, unsigned char* val, quadbyte len); virtual void SliceLocationCallback(DICOMParser* parser, doublebyte group, doublebyte element, DICOMParser::VRTypes type, unsigned char* val, quadbyte len); virtual void ImagePositionPatientCallback(DICOMParser* parser, doublebyte group, doublebyte element, DICOMParser::VRTypes type, unsigned char* val, quadbyte len); virtual void ImageOrientationPatientCallback(DICOMParser* parser, doublebyte group, doublebyte element, DICOMParser::VRTypes type, unsigned char* val, quadbyte len); virtual void SeriesUIDCallback(DICOMParser* parser, doublebyte group, doublebyte element, DICOMParser::VRTypes type, unsigned char* val, quadbyte len); virtual void SeriesDescriptionCallback(DICOMParser* parser, doublebyte group, doublebyte element, DICOMParser::VRTypes type, unsigned char* val, quadbyte len); virtual void InstanceUIDCallback(DICOMParser* parser, doublebyte group, doublebyte element, DICOMParser::VRTypes type, unsigned char* val, quadbyte len); virtual void TransferSyntaxCallback(DICOMParser* parser, doublebyte group, doublebyte element, DICOMParser::VRTypes type, unsigned char* val, quadbyte len); virtual void BitsAllocatedCallback(DICOMParser* parser, doublebyte group, doublebyte element, DICOMParser::VRTypes type, unsigned char* val, quadbyte len); virtual void ToggleSwapBytesCallback( DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char*, quadbyte); virtual void PixelSpacingCallback(DICOMParser* parser, doublebyte group, doublebyte element, DICOMParser::VRTypes type, unsigned char* val, quadbyte len); virtual void HeightCallback(DICOMParser* parser, doublebyte group, doublebyte element, DICOMParser::VRTypes type, unsigned char* val, quadbyte len); virtual void WidthCallback(DICOMParser* parser, doublebyte group, doublebyte element, DICOMParser::VRTypes type, unsigned char* val, quadbyte len); virtual void PixelRepresentationCallback(DICOMParser* parser, doublebyte group, doublebyte element, DICOMParser::VRTypes type, unsigned char* val, quadbyte len); virtual void PhotometricInterpretationCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte len); virtual void PixelDataCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte len); virtual void RescaleOffsetCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void ROIContourSequenceCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void ContourSequenceCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void ContourImageSequenceCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void ContourGeometricTypeCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void NumberOfContourPointsCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void ContourDataCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void ReferencedInstanceUIDCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void PatientNameCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void PatientIDCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void PatientSexCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void PatientAgeCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void PatientDOBCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void StudyIDCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void StudyDescriptionCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void BodyPartCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void NumberOfSeriesInStudyCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void NumberOfStudyRelatedSeriesCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void StudyDateCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void ModalityCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void ManufacturerCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void InstitutionCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void ModelCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void ScanOptionsCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); virtual void DefaultCallback(DICOMParser* parser, doublebyte, doublebyte, DICOMParser::VRTypes, unsigned char* val, quadbyte); /** Register all the standard callbacks with the DICOM Parser. This * associates a callback with each (group, element) tag pair in the * header of the file whose data needs to be cached. */ virtual void RegisterCallbacks(DICOMParser* parser); /** Register a callback for retrieving the pixel data from a DICOM * file */ virtual void RegisterPixelDataCallback(DICOMParser* parser); /** Output information associated with a DICOM series */ void OutputSeries(); /** The next set of methods are for accessing information which is * cached when a DICOM file is processed. This allows access to * information from the header as well as the pixel data. */ /** Get the pixel spacing of the last image processed by the * DICOMParser */ float* GetPixelSpacing() { return this->PixelSpacing; } /** Get the image width of the last image processed by the * DICOMParser */ int GetWidth() { return this->Width; } /** Get the image height of the last image processed by the * DICOMParser */ int GetHeight() { return this->Height; } /** Get the dimensions (width, height) of the last image processed * by the DICOMParser */ int* GetDimensions() { return this->Dimensions; } /** Get the (DICOM) x,y,z coordinates of the first pixel in the * image (upper left hand corner) of the last image processed by the * DICOMParser */ float* GetImagePositionPatient() { return this->ImagePositionPatient; } /** Get the number of bits allocated per pixel of the last image * processed by the DICOMParser */ int GetBitsAllocated() { return this->BitsAllocated; } /** Get the pixel representation of the last image processed by the * DICOMParser. A zero is a unsigned quantity. A one indicates a * signed quantity. */ int GetPixelRepresentation() { return this->PixelRepresentation; } /** Get the number of components of the last image processed by the * DICOMParser. */ unsigned int GetNumberOfComponents() { if (!this->PhotometricInterpretation) { return 1; } // // DICOM standard says that spaces (0x20) are to // be ignored for CS types. We don't handle this // well yet. // dicom_stl::string str1(*this->PhotometricInterpretation); dicom_stl::string rgb("RGB "); if (str1 == rgb) { return 3; } else { return 1; } } /** Get the transfer syntax UID for the last image processed by the * DICOMParser. */ dicom_stl::string GetTransferSyntaxUID() { return *(this->TransferSyntaxUID); } /** Get a textual description of the transfer syntax of the last * image processed by the DICOMParser. */ const char* TransferSyntaxUIDDescription(const char* uid); /** Get the image data from the last image processed by the * DICOMParser. The data is only valid if the PixelDataCallback was * registered. * \sa RegisterPixelDataCallback() */ void GetImageData(void*& data, DICOMParser::VRTypes& dataType, unsigned long& len); /** Determine whether the image data was rescaled (by the * RescaleSlope tag) to be floating point. */ bool RescaledImageDataIsFloat(); /** Determine whether the image data was rescaled (by the * RescaleSlope tag) to be a signed data type. */ bool RescaledImageDataIsSigned(); /** Get the slice number of the last image processed by the DICOMParser. */ int GetSliceNumber() { return this->SliceNumber; } /** Get the series UID for the current file. */ std::string GetSeriesUID() { return this->CurrentSeriesUID; } /** Get the series description for the current file. */ std::string GetSeriesDescription() { return this->CurrentSeriesDescription; } /** Get the patient name processed by the DICOMParser. */ void GetPatientName(char* name) { strcpy(name, m_PatientName); } /** Get the patient ID processed by the DICOMParser. */ void GetPatientID(char* id) { strcpy(id, m_PatientID); } /** Get the patient sex processed by the DICOMParser. */ void GetPatientSex(char* sex) { strcpy(sex, m_PatientSex); } /** Get the patient age processed by the DICOMParser. */ void GetPatientAge(char* age) { strcpy(age, m_PatientAge); } /** Get the patient date of birth processed by the DICOMParser. */ void GetPatientDOB(char* dob) { strcpy(dob, m_PatientDOB); } /** Get the study ID processed by the DICOMParser. */ void GetStudyID(char* id) { strcpy(id, m_StudyID); } /** Get the description of the study processed by the DICOMParser. */ void GetStudyDescription(char* desc) { strcpy(desc, m_StudyDescription); } /** Get the body part processed by the DICOMParser. */ void GetBodyPart(char* part) { strcpy(part, m_BodyPart); } /** Get the number of series in the study processed by the DICOMParser. */ void GetNumberOfSeriesInStudy(char* number) { strcpy(number, m_NumberOfSeriesInStudy); } /** Get the number of study related series processed by the DICOMParser. */ void GetNumberOfStudyRelatedSeries(char* number) { strcpy(number, m_NumberOfStudyRelatedSeries); } /** Get the study date processed by the DICOMParser. */ void GetStudyDate(char* date) { strcpy(date, m_StudyDate); } /** Get the modality processed by the DICOMParser. */ void GetModality(char* modality) { strcpy(modality, m_Modality); } /** Get the manufacturer processed by the DICOMParser. */ void GetManufacturer(char* manu) { strcpy(manu, m_Manufacturer); } /** Get the institution processed by the DICOMParser. */ void GetInstitution(char* ins) { strcpy(ins, m_Institution); } /** Get the model processed by the DICOMParser. */ void GetModel(char* model) { strcpy(model, m_Model); } /** Get the scan options name processed by the DICOMParser. */ void GetScanOptions(char* options) { strcpy(options, m_ScanOptions); } /** Clear the internal databases. This will reset the internal * databases that are grouping filenames based on SeriesUID's and * ordering filenames based on image locations. */ void Clear(); /** Get the series UIDs for the files processed since the last * clearing of the cache. */ void GetSeriesUIDs(dicom_stl::vector& v); /** Get the series Descriptions for the files processed since the last * clearing of the cache. */ void GetSeriesDescriptions(dicom_stl::vector& v); /** Get the body parts for the files processed since the last * clearing of the cache. */ void GetBodyParts(dicom_stl::vector& v); /** Get the scane options for the files processed since the last * clearing of the cache. */ void GetScanOptions(dicom_stl::vector& v); /** Get the filenames for a series ordered by slice number. */ void GetSliceNumberFilenamePairs(const dicom_stl::string& seriesUID, dicom_stl::vector>& v, bool ascending = true); /** Get the filenames for a series order by slice number. Use the first series by default. */ void GetSliceNumberFilenamePairs( dicom_stl::vector>& v, bool ascending = true); /* Get the filenames for a series ordered by slice location. */ void GetSliceLocationFilenamePairs(const dicom_stl::string& seriesUID, dicom_stl::vector>& v, bool ascending = true); /* Get the filenames for a series ordered by slice location. Use the * first series by default. */ void GetSliceLocationFilenamePairs( dicom_stl::vector>& v, bool ascending = true); /* Get the filenames for a series ordered by image position patient. This is the most reliable way to order the images in a series. */ void GetImagePositionPatientFilenamePairs(const dicom_stl::string& seriesUID, dicom_stl::vector>& v, bool ascending = true); /* Get the filenames for a series ordered by image position patient. This is the most reliable way to order the images in a series. Use the first series by default. */ void GetImagePositionPatientFilenamePairs( dicom_stl::vector>& v, bool ascending = true); /* Get the contours for a series. A vector of contours is returned where each contour is a vector of floats (x, y, z, x, y, z, x, y, z...). */ void GetContours( const dicom_stl::string& seriesUID, dicom_stl::vector>& v); /* Get the contours for a series. A vector of contours is returned where each contour is a vector of floats (x, y, z, x, y, z, x, y, z...). Use the first series by default. */ void GetContours(dicom_stl::vector>& v); /* Get the referenced instance UIDs for a series. A vector of * strings in returned. */ void GetReferencedInstanceUIDs( const dicom_stl::string& seriesUID, dicom_stl::vector& v); /* Get the referenced instance UIDs for a series. A vector of * strings in returned. Use the first series by default. */ void GetReferencedInstanceUIDs(dicom_stl::vector& v); /** Get the filename for a specific instance UID */ dicom_stl::string GetFileName(const dicom_stl::string& instanceUID); protected: int FileCount; int BitsAllocated; bool ByteSwapData; float PixelSpacing[3]; int Width; int Height; int SliceNumber; int Dimensions[2]; float ImagePositionPatient[3]; short VolumeSliceSize; short VolumeSliceCount; long VolumeVoxelCount; long VolumeSegmentCount; char m_PatientName[512]; char m_PatientID[512]; char m_PatientDOB[512]; char m_StudyID[512]; char m_StudyDescription[512]; char m_BodyPart[512]; char m_NumberOfSeriesInStudy[512]; char m_NumberOfStudyRelatedSeries[512]; char m_PatientSex[512]; char m_PatientAge[512]; char m_StudyDate[512]; char m_Modality[512]; char m_Manufacturer[512]; char m_Institution[512]; char m_Model[512]; char m_ScanOptions[512]; typedef dicom_stl::map, DICOMTagInfo> TagMapType; // TagMapType TagMap; dicom_stream::ofstream HeaderFile; // 0 unsigned // 1 2s complement (signed) int PixelRepresentation; dicom_stl::string* PhotometricInterpretation; dicom_stl::string* TransferSyntaxUID; dicom_stl::string CurrentSeriesUID; dicom_stl::string CurrentSeriesDescription; dicom_stl::string CurrentBodyPart; dicom_stl::string CurrentScanOptions; dicom_stl::string InstanceUID; float RescaleOffset; float RescaleSlope; void* ImageData; DICOMParser::VRTypes ImageDataType; unsigned long ImageDataLengthInBytes; DICOMMemberCallback* SeriesUIDCB; DICOMMemberCallback* SeriesDescriptionCB; DICOMMemberCallback* InstanceUIDCB; DICOMMemberCallback* SliceNumberCB; DICOMMemberCallback* SliceLocationCB; DICOMMemberCallback* ImagePositionPatientCB; DICOMMemberCallback* ImageOrientationPatientCB; DICOMMemberCallback* TransferSyntaxCB; DICOMMemberCallback* ToggleSwapBytesCB; DICOMMemberCallback* BitsAllocatedCB; DICOMMemberCallback* PixelSpacingCB; DICOMMemberCallback* HeightCB; DICOMMemberCallback* WidthCB; DICOMMemberCallback* PixelRepresentationCB; DICOMMemberCallback* PhotometricInterpretationCB; DICOMMemberCallback* RescaleOffsetCB; DICOMMemberCallback* RescaleSlopeCB; DICOMMemberCallback* PixelDataCB; DICOMMemberCallback* ROIContourSequenceCB; DICOMMemberCallback* ContourSequenceCB; DICOMMemberCallback* ContourDataCB; DICOMMemberCallback* NumberOfContourPointsCB; DICOMMemberCallback* ContourGeometricTypeCB; DICOMMemberCallback* ContourImageSequenceCB; DICOMMemberCallback* ReferencedInstanceUIDCB; DICOMMemberCallback* DefaultCB; DICOMMemberCallback* PatientNameCB; DICOMMemberCallback* PatientIDCB; DICOMMemberCallback* PatientSexCB; DICOMMemberCallback* PatientAgeCB; DICOMMemberCallback* StudyDateCB; DICOMMemberCallback* ModalityCB; DICOMMemberCallback* ManufacturerCB; DICOMMemberCallback* InstitutionCB; DICOMMemberCallback* ModelCB; DICOMMemberCallback* ScanOptionsCB; DICOMMemberCallback* PatientDOBCB; DICOMMemberCallback* StudyIDCB; DICOMMemberCallback* StudyDescriptionCB; DICOMMemberCallback* BodyPartCB; DICOMMemberCallback* NumberOfSeriesInStudyCB; DICOMMemberCallback* NumberOfStudyRelatedSeriesCB; // // Implementation contains stl templated classes that // can't be exported from a DLL in Windows. We hide // them in the implementation to get rid of annoying // compile warnings. // DICOMAppHelperImplementation* Implementation; private: DICOMAppHelper(const DICOMAppHelper&); void operator=(const DICOMAppHelper&); }; } // namespace DICOMPARSER_NAMESPACE #ifdef _MSC_VER #pragma warning(pop) #endif #endif