1 /*
2  *
3  *  Copyright (C) 2015-2019, Open Connections GmbH
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation are maintained by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *
14  *  Module:  dcmfg
15  *
16  *  Author:  Michael Onken
17  *
18  *  Purpose: Class for managing common functional group types
19  *
20  */
21 
22 #include "dcmtk/config/osconfig.h"
23 
24 #include "dcmtk/dcmdata/dcerror.h"
25 #include "dcmtk/dcmfg/fgbase.h"
26 #include "dcmtk/dcmfg/fgdefine.h"
27 #include "dcmtk/dcmfg/fgtypes.h"
28 #include "dcmtk/dcmiod/iodcommn.h"
29 
30 OFLogger DCM_dcmfgLogger = OFLog::getLogger("dcmtk.dcmfg");
31 
32 /*---------------------------------*
33  *  constant definitions
34  *---------------------------------*/
35 
36 // Error Conditions
37 makeOFConditionConst(FG_EC_DoubledFG, OFM_dcmfg, 1, OF_error, "Doubled Functional Group");
38 makeOFConditionConst(FG_EC_NoSuchGroup, OFM_dcmfg, 2, OF_error, "No such Functional Group");
39 makeOFConditionConst(FG_EC_NotEnoughItems, OFM_dcmfg, 3, OF_error, "Not enough Items in Functional Group");
40 makeOFConditionConst(FG_EC_TooManyItems, OFM_dcmfg, 4, OF_error, "Too many Items in Functional Group");
41 makeOFConditionConst(FG_EC_InvalidData, OFM_dcmfg, 5, OF_error, "Invalid data in Functional Group");
42 makeOFConditionConst(FG_EC_CouldNotWriteFG, OFM_dcmfg, 6, OF_error, "Could not write Functional Group");
43 makeOFConditionConst(FG_EC_CouldNotInsertFG, OFM_dcmfg, 7, OF_error, "Could not insert Functional Group");
44 makeOFConditionConst(FG_EC_NoSharedFG, OFM_dcmfg, 8, OF_error, "No shared Functional Groups found");
45 makeOFConditionConst(FG_EC_NoPerFrameFG, OFM_dcmfg, 9, OF_error, "No Per-Frame Functional Groups found");
46 makeOFConditionConst(FG_EC_CouldNotCreateFG, OFM_dcmfg, 10, OF_error, "Could not create Functional Group");
47 makeOFConditionConst(FG_EC_CouldNotReadSourceImage, OFM_dcmfg, 11, OF_error, "Could not read source image");
48 makeOFConditionConst(FG_EC_CouldNotAddFG, OFM_dcmfg, 12, OF_error, "Could add Functional Group");
49 makeOFConditionConst(FG_EC_NotEnoughFrames, OFM_dcmfg, 13, OF_error, "Not enough frames");
50 makeOFConditionConst(FG_EC_NoStacksFound, OFM_dcmfg, 14, OF_error, "No stacks found");
51 makeOFConditionConst(FG_EC_SOPClassForbidsConcatenations, OFM_dcmfg, 15, OF_error, "SOP Class forbids Concatenations");
52 makeOFConditionConst(FG_EC_PixelDataMissing, OFM_dcmfg, 16, OF_error, "Pixel Data is missing");
53 makeOFConditionConst(FG_EC_PixelDataDimensionsInvalid, OFM_dcmfg, 17, OF_error, "Pixel Data dimensions invalid");
54 makeOFConditionConst(FG_EC_PixelDataTooLarge, OFM_dcmfg, 18, OF_error, "Pixel Data too large");
55 makeOFConditionConst(FG_EC_InconsistentConcatenationData, OFM_dcmfg, 19, OF_error, "Inconsistent Concatenation Data");
56 makeOFConditionConst(FG_EC_ConcatenationComplete, OFM_dcmfg, 20, OF_error, "Concatenation Complete - no more data");
57 makeOFConditionConst(FG_EC_UnsupportedPixelDataLayout, OFM_dcmfg, 21, OF_error, "Unsupported pixel data layout");
58 
FGType2OFString(const DcmFGTypes::E_FGType fgType)59 OFString DcmFGTypes::FGType2OFString(const DcmFGTypes::E_FGType fgType)
60 {
61     switch (fgType)
62     {
63         /// Undefined functional group
64         case EFG_UNDEFINED:
65             return "Undefined Functional Group Macro";
66             break;
67         /// Unknown functional group
68         case EFG_UNKNOWN:
69             return "Unknown Functional Group Macro";
70             break;
71         /// Pixel Measures
72         case EFG_PIXELMEASURES:
73             return "Pixel Measures Functional Group Macro";
74             break;
75         /// Frame Content
76         case EFG_FRAMECONTENT:
77             return "Frame Content Functional Group Macro";
78             break;
79         /// CT Acquisition Details
80         case EFG_CTACQUISITIONDETAILS:
81             return "CT Acquisition Details Functional Group Macro";
82             break;
83         /// CT Acquisition Type
84         case EFG_CTACQUISITIONTYPE:
85             return "CT Acquisition Type Functional Group Macro";
86             break;
87         /// CT Additional X-Ray Source
88         case EFG_CTADDITIONALXRAYSOURCE:
89             return "CT Additional X-Ray Source";
90             break;
91         /// CT Exposure
92         case EFG_CTEXPOSURE:
93             return "CT Exposure Functional Group Macro";
94             break;
95         case EFG_CTGEOMETRY:
96             return "CT Geometry Functional Group Macro";
97         /// CT Image Frame Type
98         case EFG_CTIMAGEFRAMETYPE:
99             return "CT Image Frame Type Functional Group Macro";
100             break;
101         /// CT Position
102         case EFG_CTPOSITION:
103             return "CT Position Functional Group Macro";
104             break;
105         /// CT Reconstruction
106         case EFG_CTRECONSTRUCTION:
107             return "CT Reconstruction Functional Group Macro";
108             break;
109         /// CT Table Dynamics
110         case EFG_CTTABLEDYNAMICS:
111             return "CT Table Dynamics Functional Group Macro";
112             break;
113         /// CT X-Ray Details
114         case EFG_CTXRAYDETAILS:
115             return "CT X-Ray Details Functional Group Macro";
116             break;
117         /// Plane Position (Patient)
118         case EFG_PLANEPOSPATIENT:
119             return "Plane Position (Patient) Functional Group Macro";
120             break;
121         /// Plane Orientation (Patient)
122         case EFG_PLANEORIENTPATIENT:
123             return "Plane Orientation (Patient) Functional Group Macro";
124             break;
125         /// Derivation Image
126         case EFG_DERIVATIONIMAGE:
127             return "Derivation Image Functional Group Macro";
128             break;
129         /// Cardiac Synchronization
130         case EFG_CARDIACSYNC:
131             return "Cardiac Synchronization Functional Group Macro";
132             break;
133         /// Frame Anatomy
134         case EFG_FRAMEANATOMY:
135             return "Frame Anatomy Functional Group Macro";
136             break;
137         /// Pixel Value Transformation or Identity Pixel Value Transformation
138         case EFG_PIXELVALUETRANSMETA:
139             return "[CT|Identity] Pixel Value Transformation Functional Group Macro";
140             break;
141         /// Frame VOI LUT or Frame VOI LUT with LUT
142         case EFG_FRAMEVOILUTMETA:
143             return "Frame VOI LUT / Frame VOI LUT with LUT Macro";
144             break;
145         /// Real World Value Mapping
146         case EFG_REALWORLDVALUEMAPPING:
147             return "Real World Value Mapping Functional Group Macro";
148             break;
149         /// Contrast/Bolus Usage
150         case EFG_CONTRASTBOLUSUSAGE:
151             return "Contrast/Bolus Usage Group Macro";
152             break;
153         /// Pixel Intensity Relationship LUT
154         case EFG_PIXELINTENSITYRELLUT:
155             return "Pixel Intensity Relation LUT Functional Group Macro";
156             break;
157         /// Frame Pixel Shift
158         case EFG_FRAMEPIXELSHIFT:
159             return "Frame Pixel Shift Functional Group Macro";
160             break;
161         /// Patient Orientation in Frame
162         case EFG_PATIENTORIENTINFRAME:
163             return "Patient Orientation in Frame Functional Group Macro";
164             break;
165         /// Frame Display Shutter
166         case EFG_FRAMEDISPLAYSHUTTER:
167             return "Frame Display Shutter Functional Group Macro";
168             break;
169         /// Respiratory Synchronization
170         case EFG_RESPIRATORYSYNC:
171             return "Respiratory Synchronization Functional Group Macro";
172             break;
173         /// Irradiation Event Identification
174         case EFG_IRRADIATIONEVENTIDENT:
175             return "Irradiation Event Identification Functional Group Macro";
176             break;
177         /// Radiopharmaceutical Usage
178         case EFG_RADIOPHARAMAUSAGE:
179             return "Radiopharmaceutical Usage Functional Group Macro";
180             break;
181         /// Parametric Map Frame Type
182         case EFG_PARAMETRICMAPFRAMETYPE:
183             return "Parametric Map Frame Type Functional Group Macro";
184             break;
185         /// Patient Physiological State
186         case EFG_PATIENTPHYSIOSTATE:
187             return "Patient Physiological State Functional Group Macro";
188             break;
189         /// Plane Position (Volume)
190         case EFG_PLANEPOSITIONVOLUME:
191             return "Plane Position (Volume) Functional Group Macro";
192             break;
193         /// Plane Orientation (Volume)
194         case EFG_PLANEORIENTVOLUME:
195             return "Plane Orientation (Volume) Functional Group Macro";
196             break;
197         /// Temporal Position Macro
198         case EFG_TEMPORALPOSITION:
199             return "Temporal Position Functional Group Macro";
200             break;
201         /// Image Data Type
202         case EFG_IMAGEDATATYPE:
203             return "Image Data Type Functional Group Macro";
204             break;
205         /// Unassigned Shared Converted Attributes Macro
206         case EFG_UNASSIGNEDSHAREDCONVERTEDATTRIBUTES:
207             return "Unassigned Shared Converted Attributes Macro";
208             break;
209         /// Segmentation Macro
210         case EFG_SEGMENTATION:
211             return "Segmentation Functional Group Macro";
212             break;
213         /// US Image Description Functional Group Macro
214         case EFG_USIMAGEDESCRIPTION:
215             return "US Image Description Functional Group Macro";
216             break;
217     }
218     return "Unknown Functional Group Macro (internal error)";
219 }
220 
tagKey2FGType(const DcmTagKey & key)221 DcmFGTypes::E_FGType DcmFGTypes::tagKey2FGType(const DcmTagKey& key)
222 {
223     // Note: Use neat value to enum trick from Alexandrescu in order to have switch statement instead?
224     if (key == DCM_PixelMeasuresSequence)
225         return EFG_PIXELMEASURES;
226     else if (key == DCM_FrameContentSequence)
227         return EFG_FRAMECONTENT;
228     else if (key == DCM_CTAcquisitionDetailsSequence)
229         return EFG_CTACQUISITIONDETAILS;
230     else if (key == DCM_CTAdditionalXRaySourceSequence)
231         return EFG_CTADDITIONALXRAYSOURCE;
232     else if (key == DCM_CTAcquisitionTypeSequence)
233         return EFG_CTACQUISITIONTYPE;
234     else if (key == DCM_CTExposureSequence)
235         return EFG_CTEXPOSURE;
236     else if (key == DCM_CTGeometrySequence)
237         return EFG_CTGEOMETRY;
238     else if (key == DCM_CTImageFrameTypeSequence)
239         return EFG_CTIMAGEFRAMETYPE;
240     else if (key == DCM_CTPositionSequence)
241         return EFG_CTPOSITION;
242     else if (key == DCM_CTReconstructionSequence)
243         return EFG_CTRECONSTRUCTION;
244     else if (key == DCM_CTTableDynamicsSequence)
245         return EFG_CTTABLEDYNAMICS;
246     else if (key == DCM_CTXRayDetailsSequence)
247         return EFG_CTXRAYDETAILS;
248     else if (key == DCM_PlanePositionSequence)
249         return EFG_PLANEPOSPATIENT;
250     else if (key == DCM_PlaneOrientationSequence)
251         return EFG_PLANEORIENTPATIENT;
252     else if (key == DCM_DerivationImageSequence)
253         return EFG_DERIVATIONIMAGE;
254     else if (key == DCM_CardiacSynchronizationSequence)
255         return EFG_CARDIACSYNC;
256     else if (key == DCM_FrameAnatomySequence)
257         return EFG_FRAMEANATOMY;
258     else if (key == DCM_PixelValueTransformationSequence)
259         return EFG_PIXELVALUETRANSMETA;
260     else if (key == DCM_FrameVOILUTSequence)
261         return EFG_FRAMEVOILUTMETA;
262     else if (key == DCM_RealWorldValueMappingSequence)
263         return EFG_REALWORLDVALUEMAPPING;
264     else if (key == DCM_ContrastBolusUsageSequence)
265         return EFG_CONTRASTBOLUSUSAGE;
266     else if (key == DCM_PixelIntensityRelationshipLUTSequence)
267         return EFG_PIXELINTENSITYRELLUT;
268     else if (key == DCM_FramePixelShiftSequence)
269         return EFG_FRAMEPIXELSHIFT;
270     else if (key == DCM_PatientOrientationInFrameSequence)
271         return EFG_PATIENTORIENTINFRAME;
272     else if (key == DCM_FrameDisplayShutterSequence)
273         return EFG_FRAMEDISPLAYSHUTTER;
274     else if (key == DCM_RespiratorySynchronizationSequence)
275         return EFG_RESPIRATORYSYNC;
276     else if (key == DCM_IrradiationEventIdentificationSequence)
277         return EFG_IRRADIATIONEVENTIDENT;
278     else if (key == DCM_RadiopharmaceuticalUsageSequence)
279         return EFG_RADIOPHARAMAUSAGE;
280     else if (key == DCM_PatientPhysiologicalStateSequence)
281         return EFG_PATIENTPHYSIOSTATE;
282     else if (key == DCM_ParametricMapFrameTypeSequence)
283         return EFG_PARAMETRICMAPFRAMETYPE;
284     else if (key == DCM_PlanePositionVolumeSequence)
285         return EFG_PLANEPOSITIONVOLUME;
286     else if (key == DCM_PlaneOrientationVolumeSequence)
287         return EFG_PLANEORIENTVOLUME;
288     else if (key == DCM_TemporalPositionSequence)
289         return EFG_TEMPORALPOSITION;
290     else if (key == DCM_ImageDataTypeSequence)
291         return EFG_IMAGEDATATYPE;
292     else if (key == DCM_UnassignedSharedConvertedAttributesSequence)
293         return EFG_UNASSIGNEDSHAREDCONVERTEDATTRIBUTES;
294     else if (key == DCM_SegmentIdentificationSequence)
295         return EFG_SEGMENTATION;
296     else if (key == DCM_USImageDescriptionSequence)
297         return EFG_USIMAGEDESCRIPTION;
298     else
299         return EFG_UNKNOWN;
300 }
301 
tagKey2FGString(const DcmTagKey & key)302 OFString DcmFGTypes::tagKey2FGString(const DcmTagKey& key)
303 {
304     E_FGType fgtype = tagKey2FGType(key);
305     return FGType2OFString(fgtype);
306 }
307