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 #include "gdcmImageReader.h"
15 #include "gdcmExplicitDataElement.h"
16 #include "gdcmImplicitDataElement.h"
17 #include "gdcmValue.h"
18 #include "gdcmFileMetaInformation.h"
19 #include "gdcmElement.h"
20 #include "gdcmPhotometricInterpretation.h"
21 #include "gdcmTransferSyntax.h"
22 #include "gdcmAttribute.h"
23 #include "gdcmImageHelper.h"
24 #include "gdcmPrivateTag.h"
25 #include "gdcmJPEGCodec.h"
26 
27 namespace gdcm
28 {
ImageReader()29 ImageReader::ImageReader()
30 {
31   PixelData = new Image;
32 }
33 
34 ImageReader::~ImageReader()
35 = default;
36 
GetImage() const37 const Image& ImageReader::GetImage() const
38 {
39   return dynamic_cast<const Image&>(*PixelData);
40 }
GetImage()41 Image& ImageReader::GetImage()
42 {
43   return dynamic_cast<Image&>(*PixelData);
44 }
45 
46 //void ImageReader::SetImage(Image const &img)
47 //{
48 //  PixelData = img;
49 //}
50 
Read()51 bool ImageReader::Read()
52 {
53   return PixmapReader::Read();
54 }
55 
ReadImage(MediaStorage const & ms)56 bool ImageReader::ReadImage(MediaStorage const &ms)
57 {
58   if( !PixmapReader::ReadImage(ms) )
59     {
60     return false;
61     }
62   //const DataSet &ds = F->GetDataSet();
63   Image& pixeldata = GetImage();
64 
65   // 4 1/2 Let's do Pixel Spacing
66   std::vector<double> spacing = ImageHelper::GetSpacingValue(*F);
67   // FIXME: Only SC is allowed not to have spacing:
68   if( !spacing.empty() )
69     {
70     assert( spacing.size() >= pixeldata.GetNumberOfDimensions() ); // In MR, you can have a Z spacing, but store a 2D image
71     pixeldata.SetSpacing( &spacing[0] );
72     if( spacing.size() > pixeldata.GetNumberOfDimensions() ) // FIXME HACK
73       {
74       pixeldata.SetSpacing(pixeldata.GetNumberOfDimensions(), spacing[pixeldata.GetNumberOfDimensions()] );
75       }
76     }
77   // 4 2/3 Let's do Origin
78   std::vector<double> origin = ImageHelper::GetOriginValue(*F);
79   if( !origin.empty() )
80     {
81     pixeldata.SetOrigin( &origin[0] );
82     if( origin.size() > pixeldata.GetNumberOfDimensions() ) // FIXME HACK
83       {
84       pixeldata.SetOrigin(pixeldata.GetNumberOfDimensions(), origin[pixeldata.GetNumberOfDimensions()] );
85       }
86     }
87 
88   std::vector<double> dircos = ImageHelper::GetDirectionCosinesValue(*F);
89   if( !dircos.empty() )
90     {
91     pixeldata.SetDirectionCosines( &dircos[0] );
92     }
93 
94   // Do the Rescale Intercept & Slope
95   std::vector<double> is = ImageHelper::GetRescaleInterceptSlopeValue(*F);
96   pixeldata.SetIntercept( is[0] );
97   pixeldata.SetSlope( is[1] );
98 
99   return true;
100 }
101 
ReadACRNEMAImage()102 bool ImageReader::ReadACRNEMAImage()
103 {
104   if( !PixmapReader::ReadACRNEMAImage() )
105     {
106     return false;
107     }
108   const DataSet &ds = F->GetDataSet();
109   Image& pixeldata = GetImage();
110 
111   // 4 1/2 Let's do Pixel Spacing
112   const Tag tpixelspacing(0x0028, 0x0030);
113   if( ds.FindDataElement( tpixelspacing ) )
114     {
115     const DataElement& de = ds.GetDataElement( tpixelspacing );
116     Attribute<0x0028,0x0030> at;
117     at.SetFromDataElement( de );
118     pixeldata.SetSpacing( 0, at.GetValue(0));
119     pixeldata.SetSpacing( 1, at.GetValue(1));
120     }
121   // 4 2/3 Let's do Origin
122   const Tag timageposition(0x0020, 0x0030);
123   if( ds.FindDataElement( timageposition) )
124     {
125     const DataElement& de = ds.GetDataElement( timageposition);
126     Attribute<0x0020,0x0030> at = {{}};
127     at.SetFromDataElement( de );
128     pixeldata.SetOrigin( at.GetValues() );
129     if( at.GetNumberOfValues() > pixeldata.GetNumberOfDimensions() ) // FIXME HACK
130       {
131       pixeldata.SetOrigin(pixeldata.GetNumberOfDimensions(), at.GetValue(pixeldata.GetNumberOfDimensions()) );
132       }
133     }
134   const Tag timageorientation(0x0020, 0x0035);
135   if( ds.FindDataElement( timageorientation) )
136     {
137     const DataElement& de = ds.GetDataElement( timageorientation);
138     Attribute<0x0020,0x0035> at = {{1,0,0,0,1,0}};//to get rid of brackets warnings in linux, lots of {}
139     at.SetFromDataElement( de );
140     pixeldata.SetDirectionCosines( at.GetValues() );
141     }
142 
143   // Do the Rescale Intercept & Slope
144   std::vector<double> is = ImageHelper::GetRescaleInterceptSlopeValue(*F);
145   pixeldata.SetIntercept( is[0] );
146   pixeldata.SetSlope( is[1] );
147 
148   return true;
149 }
150 
151 
152 } // end namespace gdcm
153