fw4spl
ImageLazyReader.hpp
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 #pragma once
8 
9 #include "fwDcmtkIO/config.hpp"
10 #include "fwDcmtkIO/helper/Codec.hpp"
11 
12 #include <fwMedData/DicomSeries.hpp>
13 
14 #include <fwTools/Type.hpp>
15 
16 #include <dcmtk/config/osconfig.h>
17 #include <dcmtk/dcmdata/dcdeftag.h>
18 #include <dcmtk/dcmdata/dcfilefo.h>
19 #include <dcmtk/dcmdata/dcistrmb.h>
20 #include <dcmtk/dcmimgle/dcmimage.h>
21 #include <dcmtk/dcmnet/diutil.h>
22 
23 namespace fwDcmtkIO
24 {
25 namespace reader
26 {
27 namespace main
28 {
29 
33 class FWDCMTKIO_CLASS_API ImageLazyReader
34 {
35 public:
46  FWDCMTKIO_API static void* createInstanceBuffer(unsigned int rows, unsigned int columns,
47  const ::fwMemory::BufferObject::sptr& instance,
48  double rescaleSlope,
49  double rescaleIntercept,
50  unsigned short pixelRepresentation,
51  ::fwTools::Type imageType)
52  {
53  if (pixelRepresentation == 0)
54  {
55  // Use unsigned char
56  if(imageType.sizeOf() == 1)
57  {
58  return ::fwDcmtkIO::reader::main::ImageLazyReader::createInstanceBuffer< Uint8 >(
59  rows, columns, instance, rescaleSlope, rescaleIntercept, imageType);
60  }
61  // Use unsigned short
62  else
63  {
64  return ::fwDcmtkIO::reader::main::ImageLazyReader::createInstanceBuffer< Uint16 >(
65  rows, columns, instance, rescaleSlope, rescaleIntercept, imageType);
66  }
67  }
68  else
69  {
70  // Use signed chart
71  if(imageType.sizeOf() == 1)
72  {
73  return ::fwDcmtkIO::reader::main::ImageLazyReader::createInstanceBuffer< Sint8 >(
74  rows, columns, instance, rescaleSlope, rescaleIntercept, imageType);
75  }
76  // Use signed short
77  else
78  {
79  return ::fwDcmtkIO::reader::main::ImageLazyReader::createInstanceBuffer< Sint16 >(
80  rows, columns, instance, rescaleSlope, rescaleIntercept, imageType);
81  }
82  }
83  }
84 
85 protected:
86 
97  template< typename T >
98  FWDCMTKIO_API static void* createInstanceBuffer(unsigned int rows, unsigned int columns,
99  const ::fwMemory::BufferObject::sptr& instance,
100  double rescaleSlope,
101  double rescaleIntercept,
102  ::fwTools::Type imageType)
103  {
104  void* tempoBuffer = 0;
105 
106  //Copy the temporary buffer to the final buffer
107  if (imageType == ::fwTools::Type::s_INT8)
108  {
109  tempoBuffer = ::fwDcmtkIO::reader::main::ImageLazyReader::createInstanceBuffer< T, std::int8_t >(
110  rows, columns, instance, rescaleSlope, rescaleIntercept);
111  }
112  else if (imageType == ::fwTools::Type::s_INT16)
113  {
114  tempoBuffer = ::fwDcmtkIO::reader::main::ImageLazyReader::createInstanceBuffer< T, std::int16_t >(
115  rows, columns, instance, rescaleSlope, rescaleIntercept);
116  }
117  else if (imageType == ::fwTools::Type::s_INT32)
118  {
119  tempoBuffer = ::fwDcmtkIO::reader::main::ImageLazyReader::createInstanceBuffer< T, std::int32_t >(
120  rows, columns, instance, rescaleSlope, rescaleIntercept);
121  }
122  else if (imageType == ::fwTools::Type::s_INT64)
123  {
124  tempoBuffer = ::fwDcmtkIO::reader::main::ImageLazyReader::createInstanceBuffer< T, std::int64_t >(
125  rows, columns, instance, rescaleSlope, rescaleIntercept);
126  }
127  else if (imageType == ::fwTools::Type::s_UINT8)
128  {
129  tempoBuffer = ::fwDcmtkIO::reader::main::ImageLazyReader::createInstanceBuffer< T, std::uint8_t >(
130  rows, columns, instance, rescaleSlope, rescaleIntercept);
131  }
132  else if (imageType == ::fwTools::Type::s_UINT16)
133  {
134  tempoBuffer = ::fwDcmtkIO::reader::main::ImageLazyReader::createInstanceBuffer< T, std::uint16_t >(
135  rows, columns, instance, rescaleSlope, rescaleIntercept);
136  }
137  else if (imageType == ::fwTools::Type::s_UINT32)
138  {
139  tempoBuffer = ::fwDcmtkIO::reader::main::ImageLazyReader::createInstanceBuffer< T, std::uint32_t >(
140  rows, columns, instance, rescaleSlope, rescaleIntercept);
141  }
142  else if (imageType == ::fwTools::Type::s_UINT64)
143  {
144  tempoBuffer = ::fwDcmtkIO::reader::main::ImageLazyReader::createInstanceBuffer< T, std::uint64_t >(
145  rows, columns, instance, rescaleSlope, rescaleIntercept);
146  }
147  else if (imageType == ::fwTools::Type::s_FLOAT)
148  {
149  tempoBuffer = ::fwDcmtkIO::reader::main::ImageLazyReader::createInstanceBuffer< T, float >(
150  rows, columns, instance, rescaleSlope, rescaleIntercept);
151  }
152  else if (imageType == ::fwTools::Type::s_DOUBLE)
153  {
154  tempoBuffer = ::fwDcmtkIO::reader::main::ImageLazyReader::createInstanceBuffer< T, double >(
155  rows, columns, instance, rescaleSlope, rescaleIntercept);
156  }
157 
158  return tempoBuffer;
159 
160  }
161 
172  template< typename T, typename U >
173  FWDCMTKIO_API static U* createInstanceBuffer(unsigned int rows,
174  unsigned int columns,
175  const ::fwMemory::BufferObject::sptr& instance,
176  double rescaleSlope,
177  double rescaleIntercept)
178  {
179  DcmFileFormat fileFormat;
180  OFCondition status;
181  DcmDataset* dataset;
182 
183  // Register codecs
185 
186  // Create temporary buffer
187  U* tempoBuffer = new U[rows * columns];
188 
189  // Read instance
190  const size_t buffSize = instance->getSize();
191  const std::string dicomPath = instance->getStreamInfo().fsFile.string();
192  ::fwMemory::BufferObject::Lock lock(instance);
193  char* buffer = static_cast< char* >( lock.getBuffer() );
194 
195  DcmInputBufferStream is;
196  is.setBuffer(buffer, offile_off_t(buffSize));
197  is.setEos();
198 
199  fileFormat.transferInit();
200  if (!fileFormat.read(is).good())
201  {
202  FW_RAISE("Unable to read Dicom file '"<< dicomPath <<"'");
203  }
204 
205  fileFormat.loadAllDataIntoMemory();
206  fileFormat.transferEnd();
207 
208  dataset = fileFormat.getDataset();
209 
210  // Decompress data set if compressed
211  dataset->chooseRepresentation(EXS_LittleEndianExplicit, NULL);
212 
213  if(sizeof(T) == 1)
214  {
215  const Uint8* pixelData;
216  dataset->findAndGetUint8Array(DCM_PixelData, pixelData);
217  OSLM_WARN_IF("Unable to read pixel data.", !pixelData);
218 
219  for (unsigned int x = 0; x < columns; ++x)
220  {
221  for (unsigned int y = 0; y < rows; ++y)
222  {
223  unsigned int position = y + (x * rows);
224  T value;
225  value = static_cast<T>((pixelData) ? pixelData[position] : 0);
226  tempoBuffer[position] = static_cast<U>(rescaleSlope * value + rescaleIntercept);
227  }
228  }
229  }
230  else
231  {
232  const Uint16* pixelData;
233  dataset->findAndGetUint16Array(DCM_PixelData, pixelData);
234  OSLM_WARN_IF("Unable to read pixel data.", !pixelData);
235 
236  for (unsigned int x = 0; x < columns; ++x)
237  {
238  for (unsigned int y = 0; y < rows; ++y)
239  {
240  unsigned int position = y + (x * rows);
241  T value;
242  value = static_cast<T>((pixelData) ? pixelData[position] : 0);
243  tempoBuffer[position] = static_cast<U>(rescaleSlope * value + rescaleIntercept);
244  }
245  }
246  }
247 
248  // Clean up codecs
250 
251  return tempoBuffer;
252  }
253 };
254 
255 } //main
256 } //reader
257 } //fwDcmtkIO
This class is used to read the buffer of a DICOM image in LAZY mode.
static FWDCMTKIO_API void registerCodecs()
Load DICOM codec.
Definition: Codec.cpp:18
base class for BufferObject Lock
static FWDCMTKIO_API U * createInstanceBuffer(unsigned int rows, unsigned int columns, const ::fwMemory::BufferObject::sptr &instance, double rescaleSlope, double rescaleIntercept)
Create an instance buffer according to the image type. The template T is used to determine if we must...
LockBase< T >::BufferType getBuffer() const
Returns BufferObject&#39;s buffer pointer.
Class describing an elementary C++ type aka unsigned char, signed char, .... int, float...
Definition: Type.hpp:32
static FWDCMTKIO_API void cleanup()
Clean up codec register.
Definition: Codec.cpp:29
fwDcmtkIO contains classes used to pull Dicom images from a pacs using dcmtk library.
Definition: Codec.hpp:12
#define OSLM_WARN_IF(message, cond)
Definition: spyLog.hpp:267
static FWDCMTKIO_API void * createInstanceBuffer(unsigned int rows, unsigned int columns, const ::fwMemory::BufferObject::sptr &instance, double rescaleSlope, double rescaleIntercept,::fwTools::Type imageType)
Create an instance buffer according to the image type. The template T is used to determine if we must...
static FWDCMTKIO_API void * createInstanceBuffer(unsigned int rows, unsigned int columns, const ::fwMemory::BufferObject::sptr &instance, double rescaleSlope, double rescaleIntercept, unsigned short pixelRepresentation,::fwTools::Type imageType)
Create an instance buffer according to the image type.
FWTOOLS_API unsigned char sizeOf() const
Return the sizeof of the type.
Definition: Type.cpp:168