fw4spl
io/fwGdcmIO/src/fwGdcmIO/writer/ie/Image.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2018.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "fwGdcmIO/writer/ie/Image.hpp"
8 
9 #include "fwGdcmIO/helper/DicomDataTools.hpp"
10 #include "fwGdcmIO/helper/DicomDataWriter.hxx"
11 
12 #include <fwData/Image.hpp>
13 
14 #include <fwDataTools/helper/ImageGetter.hpp>
15 
16 #include <gdcmImageWriter.h>
17 
18 namespace fwGdcmIO
19 {
20 namespace writer
21 {
22 namespace ie
23 {
24 
25 //------------------------------------------------------------------------------
26 
27 Image::Image(const SPTR(::gdcm::Writer)& writer,
28  const SPTR(::fwGdcmIO::container::DicomInstance)& instance,
29  const ::fwData::Image::csptr& image,
30  const ::fwLog::Logger::sptr& logger,
31  ProgressCallback progress,
32  CancelRequestedCallback cancel) :
33  ::fwGdcmIO::writer::ie::InformationEntity< ::fwData::Image >(writer, instance, image, logger, progress, cancel)
34 {
35 }
36 
37 //------------------------------------------------------------------------------
38 
40 {
41 }
42 
43 //------------------------------------------------------------------------------
44 
46 {
47  // Nothing to write
48 }
49 
50 //------------------------------------------------------------------------------
51 
52 void Image::writeGeneralImageModuleSpecificTags(unsigned int instanceNumber)
53 {
54  // Retrieve dataset
55  ::gdcm::DataSet& dataset = m_writer->GetFile().GetDataSet();
56 
57  // Instance Number
58  ::fwGdcmIO::helper::DicomDataWriter::setTagValue< int, 0x0020, 0x0013 >(instanceNumber, dataset);
59 
60 }
61 
62 //------------------------------------------------------------------------------
63 
65 {
66  // Retrieve dataset
67  ::gdcm::DataSet& dataset = m_writer->GetFile().GetDataSet();
68 
69  // Retrieve GDCM image
70  SPTR(::gdcm::ImageWriter) imageWriter = std::static_pointer_cast< ::gdcm::ImageWriter >(m_writer);
71  ::gdcm::Image& gdcmImage = imageWriter->GetImage();
72 
73  // Pixel Spacing - Type 1
74  // WARNING : some DICOM image have not any spacing (NOT SUPPORTED BY FW4SPL), but stuff like "Pixel Aspect Ratio"
75  const std::size_t dimension = m_object->getNumberOfDimensions();
76  const std::vector< double >& spacing = m_object->getSpacing();
77  for (unsigned int i = 0; i < dimension; ++i)
78  {
79  gdcmImage.SetSpacing(i, spacing[i]);
80  }
81  OSLM_TRACE("Image's spacing : " << spacing[0] << "x" << spacing[1] << "x" << spacing[2]);
82 
83  // Slice Thickness - Type 2
84  // NOTE: ::gdcm::ImageWriter may replace SliceThickness values according to Image Origins
85  ::fwGdcmIO::helper::DicomDataWriter::setTagValue< double, 0x0018, 0x0050 >(spacing[2], dataset);
86 
87  // Image Orientation (Patient) - Type 1
88  // This tag his handled by gdcm writer
89 
90 }
91 
92 //------------------------------------------------------------------------------
93 
94 void Image::writeImagePlaneModuleSpecificTags(unsigned int instanceNumber)
95 {
96  // Retrieve GDCM image
97  SPTR(::gdcm::ImageWriter) imageWriter = std::static_pointer_cast< ::gdcm::ImageWriter >(m_writer);
98  ::gdcm::Image& gdcmImage = imageWriter->GetImage();
99 
100  // Image Position (Patient) - Type 1
101  const std::vector< double >& origin = m_object->getOrigin();
102  const std::vector< double >& spacing = m_object->getSpacing();
103  gdcmImage.SetOrigin(0, origin[0]);
104  gdcmImage.SetOrigin(1, origin[1]);
105  gdcmImage.SetOrigin(2, origin[2] + spacing[2]*instanceNumber);
106 }
107 
108 //------------------------------------------------------------------------------
109 
111 {
112  // Retrieve GDCM image
113  ::gdcm::ImageWriter* imageWriter = std::static_pointer_cast< ::gdcm::ImageWriter >(m_writer).get();
114  ::gdcm::Image& gdcmImage = imageWriter->GetImage();
115 
116  // Image's photometric interpretation - Type 1
117  ::gdcm::PhotometricInterpretation photoInter =
119  gdcmImage.SetPhotometricInterpretation(photoInter);
120  OSLM_TRACE("Image's photometric interpretation : " << photoInter);
121 
122  // Image's pixel type
123  ::gdcm::PixelFormat pixelFormat = ::fwGdcmIO::helper::DicomDataTools::getPixelType(m_object);
124  gdcmImage.SetPixelFormat(pixelFormat);
125  OSLM_TRACE("Image's pixel type : " << pixelFormat);
126 
127  //Image's number of dimension
128  unsigned int dimension =
129  static_cast<unsigned int>((m_instance->getIsMultiFiles()) ? 2 : m_object->getNumberOfDimensions());
130  gdcmImage.SetNumberOfDimensions(dimension);
131  OSLM_TRACE("Image's number of dimensions : " << dimension);
132 
133  // Image's dimension
134  const ::fwData::Image::SizeType& size = m_object->getSize();
135  for (unsigned int i = 0; i < dimension; ++i)
136  {
137  gdcmImage.SetDimension(i, static_cast<unsigned int>(size[i]));
138  }
139  OSLM_TRACE("Image's dimensions : " << size[0] << "x" << size[1] << "x" << size[2]);
140 
141 }
142 
143 //------------------------------------------------------------------------------
144 
145 void Image::writeImagePixelModuleSpecificTags(unsigned int instanceNumber)
146 {
147  SLM_ASSERT("Wrong instance number.", m_instance->getIsMultiFiles() || instanceNumber == 0);
148 
149  // Retrieve GDCM image
150  ::gdcm::ImageWriter* imageWriter = std::static_pointer_cast< ::gdcm::ImageWriter >(m_writer).get();
151  ::gdcm::Image& gdcmImage = imageWriter->GetImage();
152 
153  // Compute buffer size
154  const ::fwData::Image::SizeType& size = m_object->getSize();
155  std::size_t bufferLength = size[0] * size[1] * gdcmImage.GetPixelFormat().GetPixelSize();
156  bufferLength = (!m_instance->getIsMultiFiles()) ? (bufferLength*size[2]) : bufferLength;
157 
158  // Retrieve image buffer
160  const char* imageBuffer = static_cast< char* >(imageHelper.getBuffer());
161 
162  // Pixel Data - Type 1C
163  ::gdcm::DataElement pixeldata(::gdcm::Tag(0x7fe0, 0x0010));
164  pixeldata.SetByteValue(imageBuffer + instanceNumber * bufferLength, static_cast<unsigned int>(bufferLength));
165  gdcmImage.SetDataElement(pixeldata);
166 }
167 
168 //------------------------------------------------------------------------------
169 
171 {
172  // Retrieve dataset
173  ::gdcm::DataSet& dataset = m_writer->GetFile().GetDataSet();
174 
175  const double windowCenter = m_object->getWindowCenter();
176  const double windowWidth = m_object->getWindowWidth();
177  if(windowCenter || windowWidth)
178  {
179  // Image's windows center
180  ::fwGdcmIO::helper::DicomDataWriter::setTagValues< double, 0x0028, 0x1050 >(&windowCenter, 1, dataset);
181  OSLM_TRACE("Image's window center : " << windowCenter);
182 
183  // Image's windows width
184  ::fwGdcmIO::helper::DicomDataWriter::setTagValues< double, 0x0028, 0x1051 >(&windowWidth, 1, dataset);
185  OSLM_TRACE("Image's window width : " << windowWidth);
186  }
187 
188 }
189 
190 //------------------------------------------------------------------------------
191 
193 {
194  // Retrieve dataset
195  ::gdcm::DataSet& dataset = m_writer->GetFile().GetDataSet();
196 
197  // SOP Class UID
198  ::fwGdcmIO::helper::DicomDataWriter::setTagValue< 0x0008, 0x0016 >(m_instance->getSOPClassUID(), dataset);
199  SLM_TRACE("SOP Class UID : " + m_instance->getSOPClassUID());
200 }
201 
202 //------------------------------------------------------------------------------
203 
204 void Image::writeSOPCommonModuleSpecificTags(unsigned int instanceNumber)
205 {
206  // Retrieve dataset
207  ::gdcm::DataSet& dataset = m_writer->GetFile().GetDataSet();
208 
209  // SOP Instance UID
210  const std::string sopInstanceUID = m_instance->getSOPInstanceUIDContainer()[instanceNumber];
211  ::fwGdcmIO::helper::DicomDataWriter::setTagValue< 0x0008, 0x0018 >(sopInstanceUID, dataset);
212 }
213 
214 //------------------------------------------------------------------------------
215 
217 {
218  // Retrieve dataset
219  ::gdcm::DataSet& dataset = m_writer->GetFile().GetDataSet();
220 
221  // Image Type - Type 1 - FIXME: Fake Value
222  const ::gdcm::String< 92, 16 > imageType = "ORIGINAL\\PRIMARY\\AXIAL";
223  ::fwGdcmIO::helper::DicomDataWriter::setTagValues< ::gdcm::String< 92, 16 >, 0x0008, 0x0008 >(&imageType, 1,
224  dataset);
225 
226  // Acquisition Number - Type 2 - FIXME: Fake Value
227  unsigned int acquisitionNumber = 1;
228  ::fwGdcmIO::helper::DicomDataWriter::setTagValue< unsigned int, 0x0020, 0x0012 >(acquisitionNumber, dataset);
229 
230  // KVP - Type 2 - FIXME: Fake Value
231  ::fwGdcmIO::helper::DicomDataWriter::setTagValue< double, 0x0018, 0x0060 >(1, dataset);
232 
233  // Rescale Type - Type 1C - FIXME: Fake Value
234  ::fwGdcmIO::helper::DicomDataWriter::setTagValue< 0x0028, 0x1054 >("HU", dataset);
235 
236 }
237 
238 //------------------------------------------------------------------------------
239 
241 {
242  // Retrieve dataset
243  ::gdcm::DataSet& dataset = m_writer->GetFile().GetDataSet();
244 
245  // Image Type - Type 1 - FIXME: Fake Value
246  const ::gdcm::String< 92, 16 > imageType = "ORIGINAL\\PRIMARY\\MPR";
247  ::fwGdcmIO::helper::DicomDataWriter::setTagValues< ::gdcm::String< 92, 16 >, 0x0008, 0x0008 >(&imageType, 1,
248  dataset);
249 
250  // Scanning Sequence - Type 1 - FIXME: Fake Value
251  const ::gdcm::String< 92, 16 > scanningSequence = "SE";
252  ::fwGdcmIO::helper::DicomDataWriter::setTagValues< ::gdcm::String< 92, 16 >, 0x0018, 0x0020 >(&scanningSequence, 1,
253  dataset);
254 
255  // Sequence Variant - Type 1 - FIXME: Fake Value
256  const ::gdcm::String< 92, 16 > sequenceVariant = "NONE";
257  ::fwGdcmIO::helper::DicomDataWriter::setTagValues< ::gdcm::String< 92, 16 >, 0x0018, 0x0021 >(&sequenceVariant, 1,
258  dataset);
259 
260  // Scan Options - Type 2 - FIXME: Fake Value
261  const ::gdcm::String< 92, 16 > scanOption = "";
262  ::fwGdcmIO::helper::DicomDataWriter::setTagValues< ::gdcm::String< 92, 16 >, 0x0018, 0x0022 >(&scanOption, 1,
263  dataset);
264 
265  // MR Acquisition Type - Type 2 - FIXME: Fake Value
266  ::fwGdcmIO::helper::DicomDataWriter::setTagValue< 0x0018, 0x0023 >("3D", dataset);
267 
268  // Repetition Time - Type 2C - FIXME: Fake Value
269  ::fwGdcmIO::helper::DicomDataWriter::setTagValue< double, 0x0018, 0x0080 >(0, dataset);
270 
271  // Echo Time - Type 2 - FIXME: Fake Value
272  ::fwGdcmIO::helper::DicomDataWriter::setTagValue< double, 0x0018, 0x0081 >(1, dataset);
273 
274  // Echo Train Length - Type 2 - FIXME: Fake Value
275  ::fwGdcmIO::helper::DicomDataWriter::setTagValue< unsigned int, 0x0018, 0x0091 >(1, dataset);
276 }
277 
278 //------------------------------------------------------------------------------
279 
280 } // namespace ie
281 } // namespace writer
282 } // namespace fwGdcmIO
#define SPTR(_cls_)
virtual FWGDCMIO_API void writeSOPCommonModule()
Write SOP Common Module tags.
InformationEntity base class used to write modules.
This class defines a DICOM SOP instance. It is useful during the whole writing process. This class allows to share data between module writers.
FWDATATOOLS_API void * getBuffer() const
Returns image buffer.
Definition: ImageGetter.cpp:41
#define OSLM_TRACE(message)
Definition: spyLog.hpp:230
virtual FWGDCMIO_API void writeImagePixelModule()
Write Image Pixel Module tags.
virtual FWGDCMIO_API void writeGeneralImageModuleSpecificTags(unsigned int instanceNumber)
Write General Image Module specific tags.
The namespace fwGdcmIO contains reader, writer and helper for dicom data.
virtual FWGDCMIO_API void writeCTImageModule()
Write CT Image Module tags.
static FWGDCMIO_APIconst::gdcm::PhotometricInterpretation getPhotometricInterpretation(const ::fwData::Image::csptr &image)
Return the photometric interpretation of an acquisition.
std::shared_ptr< ::fwGdcmIO::container::DicomInstance > m_instance
DICOM Instance.
virtual FWGDCMIO_API void writeImagePlaneModuleSpecificTags(unsigned int instanceNumber)
Write Image Plane Module tags.
virtual FWGDCMIO_API void writeImagePlaneModule()
Write Image Plane Module tags.
#define SLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:308
virtual FWGDCMIO_API void writeImagePixelModuleSpecificTags(unsigned int instanceNumber)
Write Image Pixel Module specific tags.
FWGDCMIO_API Image(const std::shared_ptr< ::gdcm::Writer > &writer, const std::shared_ptr< ::fwGdcmIO::container::DicomInstance > &instance, const ::fwData::Image::csptr &image, const ::fwLog::Logger::sptr &logger=nullptr, ProgressCallback progress=nullptr, CancelRequestedCallback cancel=nullptr)
Constructor.
virtual FWGDCMIO_API void writeMRImageModule()
Write MR Image Module tags.
Defines an helper to modify an fwData::Image by adding few medical fields and create in parallel the ...
Definition: ImageGetter.hpp:23
#define SLM_TRACE(message)
Definition: spyLog.hpp:228
Contains the representation of the data objects used in the framework.
std::shared_ptr< const ::fwData::Image > m_object
FW4SPL Object.
virtual FWGDCMIO_API void writeVOILUTModule()
Write VOI LUT Module tags.
virtual FWGDCMIO_API void writeGeneralImageModule()
Write General Image Module tags.
static FWGDCMIO_APIconst::gdcm::PixelFormat getPixelType(const ::fwData::Image::csptr &image)
Return the pixel type of a fwData Image.
virtual FWGDCMIO_API void writeSOPCommonModuleSpecificTags(unsigned int instanceNumber)
Write SOP Common Module specific tags.