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