1 /*=========================================================================
2 
3   Program: GDCM (Grassroots DICOM). A DICOM library
4 
5   Copyright (c) 2006-2011 Mathieu Malaterre
6   All rights reserved.
7   See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
8 
9      This software is distributed WITHOUT ANY WARRANTY; without even
10      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11      PURPOSE.  See the above copyright notice for more information.
12 
13 =========================================================================*/
14 #ifndef GDCMIMAGEHELPER_H
15 #define GDCMIMAGEHELPER_H
16 
17 #include "gdcmTypes.h"
18 #include "gdcmTag.h"
19 #include <vector>
20 #include "gdcmPixelFormat.h"
21 #include "gdcmPhotometricInterpretation.h"
22 #include "gdcmSmartPointer.h"
23 #include "gdcmLookupTable.h"
24 
25 namespace gdcm
26 {
27 
28 class MediaStorage;
29 class DataSet;
30 class File;
31 class Image;
32 class Pixmap;
33 class ByteValue;
34 
35 // minimal struct:
36 struct RealWorldValueMappingContent {
37   double RealWorldValueIntercept;
38   double RealWorldValueSlope;
39   // http://dicom.nema.org/MEDICAL/DICOM/2014c/output/chtml/part16/sect_CID_7181.html
40   std::string CodeValue;
41   std::string CodeMeaning;
42 };
43 
44 /**
45  * \brief ImageHelper (internal class, not intended for user level)
46  *
47  * \details
48  * Helper for writing World images in DICOM. DICOM has a 'template' approach to image where
49  * MR Image Storage are distinct object from Enhanced MR Image Storage. For example the
50  * Pixel Spacing in one object is not at the same position (ie Tag) as in the other
51  * this class is the central (read: fragile) place where all the dispatching is done from
52  * a unified view of a world image (typically VTK or ITK point of view) down to the low
53  * level DICOM point of view.
54  *
55  * \warning: do not expect the API of this class to be maintained at any point, since as
56  * Modalities are added the API might have to be augmented or behavior changed to cope
57  * with new modalities.
58  */
59 class GDCM_EXPORT ImageHelper
60 {
61 public:
62   /// GDCM 1.x compatibility issue:
63   /// Do not use anymore. This hack was used for some MR Image Storage
64   /// generated by Philips Modality.
65   /// When "Combine MR Rescaling" is set to TRUE, rescaling is removed. But
66   /// when set to FALSE, the Modality LUT was exported. Internally GDCM now
67   /// handles this gracefully.
68   static void SetForceRescaleInterceptSlope(bool);
69   static bool GetForceRescaleInterceptSlope();
70 
71   /// Since GDCM 2.6.1 Philips Medical System are read using the Private Field
72   /// For Rescale Slope/Intercept by default. This mechanism can be deactivated
73   /// using the following API:
74   /// This option has no effect when ForceRescaleInterceptSlope is set to true
75   /// GDCM will only read those private attribute but never write them out.
76   static void SetPMSRescaleInterceptSlope(bool);
77   static bool GetPMSRescaleInterceptSlope();
78 
79   /// GDCM 1.x compatibility issue:
80   /// When using ReWrite an MR Image Storage would be rewritten as Secondary Capture Object while
81   /// still having a Pixel Spacing tag (0028,0030). If you have deal with those files, use this
82   /// very special flag to handle them
83   /// Unless explicitly set elsewhere by the standard, it will use value from 0028,0030 / 0018,0088
84   /// for the Pixel Spacing of the Image
85   static void SetForcePixelSpacing(bool);
86   static bool GetForcePixelSpacing();
87 
88   /// This function checks tags (0x0028, 0x0010) and (0x0028, 0x0011) for the
89   /// rows and columns of the image in pixels (as opposed to actual distances).
90   /// The output is {col , row}
91   static std::vector<unsigned int> GetDimensionsValue(const File& f);
92   static void SetDimensionsValue(File& f, const Pixmap & img);
93 
94   /// This function returns pixel information about an image from its dataset
95   /// That includes samples per pixel and bit depth (in that order)
96   static PixelFormat GetPixelFormatValue(const File& f);
97 
98   /// Set/Get shift/scale from/to a file
99   /// \warning this function reads/sets the Slope/Intercept in appropriate
100   /// class storage, but also Grid Scaling in RT Dose Storage
101   /// Can't take a dataset because the mediastorage of the file must be known
102   static std::vector<double> GetRescaleInterceptSlopeValue(File const & f);
103   static void SetRescaleInterceptSlopeValue(File & f, const Image & img);
104 
105   // read only for now
106   static bool GetRealWorldValueMappingContent(File const & f, RealWorldValueMappingContent & rwvmc);
107 
108   /// Set/Get Origin (IPP) from/to a file
109   static std::vector<double> GetOriginValue(File const & f);
110   static void SetOriginValue(DataSet & ds, const Image & img);
111 
112   /// Get Direction Cosines (IOP) from/to a file
113   /// Requires a file because mediastorage must be known
114   static std::vector<double> GetDirectionCosinesValue(File const & f);
115   /// Set Direction Cosines (IOP) from/to a file
116   /// When IOD does not defines what is IOP (eg. typically Secondary Capture Image Storage)
117   /// this call will simply remove the IOP attribute.
118   /// Else in case of MR/CT image storage, this call will properly lookup the correct attribute
119   /// to store the IOP.
120   // FIXME: There is a major issue for image with multiple IOP (eg. Enhanced * Image Storage).
121   static void SetDirectionCosinesValue(DataSet & ds, const std::vector<double> & dircos);
122 
123   /// Set/Get Spacing from/to a File
124   static std::vector<double> GetSpacingValue(File const & f);
125   static void SetSpacingValue(DataSet & ds, const std::vector<double> & spacing);
126 
127   /// DO NOT USE
128   static bool ComputeSpacingFromImagePositionPatient(const std::vector<double> &imageposition, std::vector<double> & spacing);
129 
130   static bool GetDirectionCosinesFromDataSet(DataSet const & ds, std::vector<double> & dircos);
131 
132   //functions to get more information from a file
133   //useful for the stream image reader, which fills in necessary image information
134   //distinctly from the reader-style data input
135   static PhotometricInterpretation GetPhotometricInterpretationValue(File const& f);
136   //returns the configuration of colors in a plane, either RGB RGB RGB or RRR GGG BBB
137   static unsigned int GetPlanarConfigurationValue(const File& f);
138 
139   /// returns the lookup table of an image file
140   static SmartPointer<LookupTable> GetLUT(File const& f);
141 
142   // Moved from PixampReader to here. Generally used for photometric interpretation.
143   static const ByteValue* GetPointerFromElement(Tag const &tag, File const& f);
144 
145   /// Moved from MediaStorage here, since we need extra info stored in PixelFormat & PhotometricInterpretation
146   static MediaStorage ComputeMediaStorageFromModality(const char *modality,
147     unsigned int dimension = 2, PixelFormat const & pf = PixelFormat(),
148     PhotometricInterpretation const & pi = PhotometricInterpretation(),
149     double rescaleintercept = 0, double rescaleslope = 1 );
150 
151 protected:
152   static Tag GetSpacingTagFromMediaStorage(MediaStorage const &ms);
153   static Tag GetZSpacingTagFromMediaStorage(MediaStorage const &ms);
154 
155 private:
156   static bool ForceRescaleInterceptSlope;
157   static bool PMSRescaleInterceptSlope;
158   static bool ForcePixelSpacing;
159 };
160 
161 } // end namespace gdcm
162 
163 #endif // GDCMIMAGEHELPER_H
164