Medical Imaging Interaction Toolkit  2018.4.99-12ad79a3
Medical Imaging Interaction Toolkit
mitkImageDataItem.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "mitkImageDataItem.h"
14 #include "mitkMemoryUtilities.h"
15 #include <vtkImageData.h>
16 #include <vtkPointData.h>
17 
18 #include <vtkBitArray.h>
19 #include <vtkCharArray.h>
20 #include <vtkDoubleArray.h>
21 #include <vtkFloatArray.h>
22 #include <vtkIntArray.h>
23 #include <vtkLongArray.h>
24 #include <vtkShortArray.h>
25 #include <vtkUnsignedCharArray.h>
26 #include <vtkUnsignedIntArray.h>
27 #include <vtkUnsignedLongArray.h>
28 #include <vtkUnsignedShortArray.h>
29 
30 #include <mitkImage.h>
33 
36  int timestep,
37  unsigned int dimension,
38  void *data,
39  bool manageMemory,
40  size_t offset)
41  : m_Data(static_cast<unsigned char *>(aParent.m_Data) + offset),
42  m_PixelType(new mitk::PixelType(aParent.GetPixelType())),
43  m_ManageMemory(false),
44  m_VtkImageData(nullptr),
45  m_VtkImageReadAccessor(nullptr),
46  m_VtkImageWriteAccessor(nullptr),
47  m_Offset(offset),
48  m_IsComplete(false),
49  m_Size(0),
50  m_Parent(&aParent),
51  m_Dimension(dimension),
52  m_Timestep(timestep)
53 {
54  // compute size
55  // const unsigned int *dims = desc->GetDimensions();
56  for (unsigned int i = 0; i < dimension; i++)
57  {
58  m_Dimensions[i] = desc->GetDimensions()[i];
59  }
60  this->ComputeItemSize(m_Dimensions, dimension);
61 
62  if (data != nullptr && data != m_Data)
63  {
64  memcpy(m_Data, data, m_Size);
65  if (manageMemory)
66  {
67  delete[](unsigned char *) data;
68  }
69  }
70 
71  m_ReferenceCount = 0;
72 }
73 
75 {
76  if (m_VtkImageData != nullptr)
77  {
78  m_VtkImageData->Delete();
79  }
80 
81  if (m_VtkImageReadAccessor != nullptr)
82  {
84  }
85  if (m_VtkImageWriteAccessor != nullptr)
86  {
88  }
89 
90  if (m_Parent.IsNull())
91  {
92  if (m_ManageMemory)
93  delete[] m_Data;
94  }
95  delete m_PixelType;
96 }
97 
99  int timestep,
100  void *data,
101  bool manageMemory)
102  : m_Data(static_cast<unsigned char *>(data)),
103  m_PixelType(new mitk::PixelType(desc->GetChannelDescriptor(0).GetPixelType())),
104  m_ManageMemory(manageMemory),
105  m_VtkImageData(nullptr),
106  m_VtkImageReadAccessor(nullptr),
107  m_VtkImageWriteAccessor(nullptr),
108  m_Offset(0),
109  m_IsComplete(false),
110  m_Size(0),
111  m_Dimension(desc->GetNumberOfDimensions()),
112  m_Timestep(timestep)
113 {
114  // compute size
115  const unsigned int *dimensions = desc->GetDimensions();
116  for (unsigned int i = 0; i < m_Dimension; i++)
117  {
118  m_Dimensions[i] = dimensions[i];
119  }
120 
121  this->ComputeItemSize(m_Dimensions, m_Dimension);
122 
123  if (m_Data == nullptr)
124  {
125  m_Data = mitk::MemoryUtilities::AllocateElements<unsigned char>(m_Size);
126  m_ManageMemory = true;
127  }
128 
129  m_ReferenceCount = 0;
130 }
131 
133  int timestep,
134  unsigned int dimension,
135  unsigned int *dimensions,
136  void *data,
137  bool manageMemory)
138  : m_Data(static_cast<unsigned char *>(data)),
139  m_PixelType(new mitk::PixelType(type)),
140  m_ManageMemory(manageMemory),
141  m_VtkImageData(nullptr),
142  m_VtkImageReadAccessor(nullptr),
143  m_VtkImageWriteAccessor(nullptr),
144  m_Offset(0),
145  m_IsComplete(false),
146  m_Size(0),
147  m_Parent(nullptr),
148  m_Dimension(dimension),
149  m_Timestep(timestep)
150 {
151  for (unsigned int i = 0; i < m_Dimension; i++)
152  {
153  m_Dimensions[i] = dimensions[i];
154  }
155 
156  this->ComputeItemSize(dimensions, dimension);
157 
158  if (m_Data == nullptr)
159  {
160  m_Data = mitk::MemoryUtilities::AllocateElements<unsigned char>(m_Size);
161  m_ManageMemory = true;
162  }
163 
164  m_ReferenceCount = 0;
165 }
166 
168  : itk::LightObject(),
169  m_Data(other.m_Data),
170  m_PixelType(new mitk::PixelType(*other.m_PixelType)),
172  m_VtkImageData(nullptr),
173  m_VtkImageReadAccessor(nullptr),
174  m_VtkImageWriteAccessor(nullptr),
175  m_Offset(other.m_Offset),
176  m_IsComplete(other.m_IsComplete),
177  m_Size(other.m_Size),
178  m_Parent(other.m_Parent),
179  m_Dimension(other.m_Dimension),
180  m_Timestep(other.m_Timestep)
181 {
182  // copy m_Data ??
183  for (int i = 0; i < MAX_IMAGE_DIMENSIONS; ++i)
184  m_Dimensions[i] = other.m_Dimensions[i];
185 }
186 
187 itk::LightObject::Pointer mitk::ImageDataItem::InternalClone() const
188 {
189  Self::Pointer newGeometry = new Self(*this);
190  newGeometry->UnRegister();
191  return newGeometry.GetPointer();
192 }
193 
194 void mitk::ImageDataItem::ComputeItemSize(const unsigned int *dimensions, unsigned int dimension)
195 {
196  m_Size = m_PixelType->GetSize();
197  for (unsigned int i = 0; i < dimension; i++)
198  {
199  m_Size *= *(dimensions + i);
200  }
201 }
202 
204 {
205  vtkImageData *inData = vtkImageData::New();
206  vtkDataArray *scalars = nullptr;
207 
208  const unsigned int *dims = m_Dimensions;
209  const unsigned int dim = m_Dimension;
210 
211  unsigned long size = 0;
212  if (dim == 1)
213  {
214  inData->SetDimensions(dims[0] - 1, 1, 1);
215  size = dims[0];
216  inData->SetOrigin(((mitk::ScalarType)dims[0]) / 2.0, 0, 0);
217  }
218  else if (dim == 2)
219  {
220  inData->SetDimensions(dims[0], dims[1], 1);
221  size = dims[0] * dims[1];
222  inData->SetOrigin(((mitk::ScalarType)dims[0]) / 2.0f, ((mitk::ScalarType)dims[1]) / 2.0f, 0);
223  }
224  else if (dim >= 3)
225  {
226  inData->SetDimensions(dims[0], dims[1], dims[2]);
227  size = dims[0] * dims[1] * dims[2];
228  // Test
229  // inData->SetOrigin( (float) dims[0] / 2.0f, (float) dims[1] / 2.0f, (float) dims[2] / 2.0f );
230  inData->SetOrigin(0, 0, 0);
231  }
232  else
233  {
234  inData->Delete();
235  return;
236  }
237 
238  if (m_Timestep >= 0)
239  {
240  SlicedGeometry3D *geom3d;
241  geom3d = iP->GetSlicedGeometry(m_Timestep);
242 
243  const mitk::Vector3D vspacing = geom3d->GetSpacing();
244  double dspacing[3] = {vspacing[0], vspacing[1], vspacing[2]};
245  inData->SetSpacing(dspacing);
246  }
247 
248  if (m_PixelType->GetComponentType() == itk::ImageIOBase::CHAR)
249  {
250  scalars = vtkCharArray::New();
251  }
252  else if (m_PixelType->GetComponentType() == itk::ImageIOBase::UCHAR)
253  {
254  scalars = vtkUnsignedCharArray::New();
255  }
256  else if (m_PixelType->GetComponentType() == itk::ImageIOBase::SHORT)
257  {
258  scalars = vtkShortArray::New();
259  }
260  else if (m_PixelType->GetComponentType() == itk::ImageIOBase::USHORT)
261  {
262  scalars = vtkUnsignedShortArray::New();
263  }
264  else if (m_PixelType->GetComponentType() == itk::ImageIOBase::INT)
265  {
266  scalars = vtkIntArray::New();
267  }
268  else if (m_PixelType->GetComponentType() == itk::ImageIOBase::UINT)
269  {
270  scalars = vtkUnsignedIntArray::New();
271  }
272  else if (m_PixelType->GetComponentType() == itk::ImageIOBase::LONG)
273  {
274  scalars = vtkLongArray::New();
275  }
276  else if (m_PixelType->GetComponentType() == itk::ImageIOBase::ULONG)
277  {
278  scalars = vtkUnsignedLongArray::New();
279  }
280  else if (m_PixelType->GetComponentType() == itk::ImageIOBase::FLOAT)
281  {
282  scalars = vtkFloatArray::New();
283  }
284  else if (m_PixelType->GetComponentType() == itk::ImageIOBase::DOUBLE)
285  {
286  scalars = vtkDoubleArray::New();
287  }
288  else
289  {
290  inData->Delete();
291  return;
292  }
293 
294  m_VtkImageData = inData;
295 
296  // set mitk imageDataItem void array to vtk scalar values
297  scalars->SetNumberOfComponents(m_PixelType->GetNumberOfComponents());
298  scalars->SetVoidArray(m_Data, size * m_PixelType->GetNumberOfComponents(), 1);
299 
300  m_VtkImageData->GetPointData()->SetScalars(scalars);
301  scalars->Delete();
302 }
303 
305 {
306  if (m_VtkImageData)
307  m_VtkImageData->Modified();
308 }
309 
311 {
312  if (m_VtkImageData == nullptr)
313  {
314  ConstructVtkImageData(iP);
315  }
316  if (m_VtkImageReadAccessor == nullptr)
317  {
318  m_VtkImageReadAccessor = new ImageVtkReadAccessor(iP, this, m_VtkImageData);
319  }
320  return m_VtkImageReadAccessor;
321 }
322 
324 {
325  if (m_VtkImageData == nullptr)
326  {
327  ConstructVtkImageData(iP.GetPointer());
328  }
329  if (m_VtkImageWriteAccessor == nullptr)
330  {
331  m_VtkImageWriteAccessor = new ImageVtkWriteAccessor(iP, this, m_VtkImageData);
332  }
333  return m_VtkImageWriteAccessor;
334 }
double ScalarType
DataCollection - Class to facilitate loading/accessing structured data.
itk::LightObject::Pointer InternalClone() const override
static Vector3D offset
ImageDataItem(const ImageDataItem &aParent, const mitk::ImageDescriptor::Pointer desc, int timestep, unsigned int dimension, void *data=nullptr, bool manageMemory=false, vcl_size_t offset=0)
unsigned char * m_Data
#define MAX_IMAGE_DIMENSIONS
Defines the maximum of 8 dimensions per image channel taken from ipPicDescriptor. ...
ImageVtkReadAccessor * GetVtkImageAccessor(ImageConstPointer) const
GetVtkImageAccessor Returns a vtkImageDataItem, if none is present, a new one is constructed by the C...
Describes the geometry of a data object consisting of slices.
virtual void Modified() const
ImageVtkReadAccessor class provides any image read access which is required by Vtk methods...
ImageVtkWriteAccessor * m_VtkImageWriteAccessor
virtual void ConstructVtkImageData(ImageConstPointer) const
const mitk::Vector3D GetSpacing() const
Get the spacing (size of a pixel).
ImageVtkReadAccessor * m_VtkImageReadAccessor
Internal class for managing references on sub-images.
ImageVtkWriteAccessor class provides any image write access which is required by Vtk methods...
Class for defining the data type of pixels.
Definition: mitkPixelType.h:51
vtkImageData * m_VtkImageData