Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkImageAccessorBase.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 "mitkImageAccessorBase.h"
18 #include "mitkImage.h"
19 
20 mitk::ImageAccessorBase::ThreadIDType mitk::ImageAccessorBase::CurrentThreadHandle()
21 {
22 #ifdef ITK_USE_SPROC
23  return GetCurrentThreadId();
24 #endif
25 
26 #ifdef ITK_USE_PTHREADS
27  return pthread_self();
28 #endif
29 
30 #ifdef ITK_USE_WIN32_THREADS
31  return GetCurrentThreadId();
32 #endif
33 }
34 
35 bool mitk::ImageAccessorBase::CompareThreadHandles(mitk::ImageAccessorBase::ThreadIDType handle1,
36  mitk::ImageAccessorBase::ThreadIDType handle2)
37 {
38  return handle1 == handle2;
39 }
40 
42 {
43 }
44 
46  const ImageDataItem *imageDataItem,
47  int OptionFlags)
48  : // m_Image(iP)
49  //, imageDataItem(iDI)
50  m_SubRegion(nullptr),
51  m_Options(OptionFlags),
52  m_CoherentMemory(false)
53 {
54  m_Thread = CurrentThreadHandle();
55 
56  // Initialize WaitLock
59 
60  // Check validity of ImageAccessor
61 
62  // Is there an Image?
63  /*
64  if(!m_Image)
65  {
66  mitkThrow() << "Invalid ImageAccessor: No Image was specified in constructor of ImageAccessor";
67  }
68  */
69 
70  if (image)
71  {
72  // Make sure, that the Image is initialized properly
73  if (image->m_Initialized == false)
74  {
75  if (image->GetSource().IsNull())
76  {
77  mitkThrow() << "ImageAccessor: No image source is defined";
78  }
79  image->m_ReadWriteLock.Lock();
80  if (image->GetSource()->Updating() == false)
81  {
82  image->GetSource()->UpdateOutputInformation();
83  }
84  image->m_ReadWriteLock.Unlock();
85  }
86  }
87 
88  // Investigate 4 cases of possible image parts/regions
89 
90  // Case 1: No ImageDataItem and no Subregion => Whole Image is accessed
91  if (imageDataItem == nullptr && m_SubRegion == nullptr)
92  {
93  m_CoherentMemory = true;
94 
95  // Organize first image channel
96  image->m_ReadWriteLock.Lock();
97  imageDataItem = image->GetChannelData();
98  image->m_ReadWriteLock.Unlock();
99 
100  // Set memory area
101  m_AddressBegin = imageDataItem->m_Data;
102  m_AddressEnd = (unsigned char *)m_AddressBegin + imageDataItem->m_Size;
103  }
104 
105  // Case 2: ImageDataItem but no Subregion
106  if (imageDataItem && m_SubRegion == nullptr)
107  {
108  m_CoherentMemory = true;
109 
110  // Set memory area
111  m_AddressBegin = imageDataItem->m_Data;
112  m_AddressEnd = (unsigned char *)m_AddressBegin + imageDataItem->m_Size;
113  }
114 
115  // Case 3: No ImageDataItem but a SubRegion
116  if (imageDataItem == nullptr && m_SubRegion)
117  {
118  mitkThrow() << "Invalid ImageAccessor: The use of a SubRegion is not supported (yet).";
119  }
120 
121  // Case 4: ImageDataItem and SubRegion
122  if (imageDataItem == nullptr && m_SubRegion)
123  {
124  mitkThrow() << "Invalid ImageAccessor: The use of a SubRegion is not supported (yet).";
125  }
126 }
127 
132 {
133  if (m_CoherentMemory)
134  {
135  if ((iAB->m_AddressBegin >= m_AddressBegin && iAB->m_AddressBegin < m_AddressEnd) ||
136  (iAB->m_AddressEnd > m_AddressBegin && iAB->m_AddressEnd <= m_AddressEnd))
137  {
138  return true;
139  }
140  if ((m_AddressBegin >= iAB->m_AddressBegin && m_AddressBegin < iAB->m_AddressEnd) ||
141  (m_AddressEnd > iAB->m_AddressBegin && m_AddressEnd <= iAB->m_AddressEnd))
142  {
143  return true;
144  }
145  }
146  else
147  {
148  GetImage()->m_ReadWriteLock.Unlock();
149  mitkThrow() << "ImageAccessor: incoherent memory area is not supported yet";
150  }
151 
152  return false;
153 }
154 
157 {
158  wL->m_Mutex.Lock();
159 
160  // Decrement
161  wL->m_WaiterCount -= 1;
162 
163  // If there are no more waiting ImageAccessors, delete the Mutex
164  // (Der Letzte macht das Licht aus!)
165  if (wL->m_WaiterCount <= 0)
166  {
167  wL->m_Mutex.Unlock();
168  delete wL;
169  }
170  else
171  {
172  wL->m_Mutex.Unlock();
173  }
174 }
175 
177 {
178 #ifdef MITK_USE_RECURSIVE_MUTEX_PREVENTION
179  // Prevent deadlock
180  ThreadIDType id = CurrentThreadHandle();
181  if (CompareThreadHandles(id, iAB->m_Thread))
182  {
183  GetImage()->m_ReadWriteLock.Unlock();
184  mitkThrow()
185  << "Prohibited image access: the requested image part is already in use and cannot be requested recursively!";
186  }
187 #endif
188 }
void WaitForReleaseOf(ImageAccessorWaitLock *wL)
Uses the WaitLock to wait for another ImageAccessor.
itk::ImageRegion< 4 > * m_SubRegion
unsigned int m_WaiterCount
Holds the number of ImageAccessors, which are waiting until the represented ImageAccessor is released...
bool Overlap(const ImageAccessorBase *iAB)
Computes if there is an Overlap of the image part between this instantiation and another ImageAccesso...
unsigned char * m_Data
ImageAccessorWaitLock * m_WaitLock
Pointer to a WaitLock struct, that allows other ImageAccessors to wait for this ImageAccessor.
#define mitkThrow()
void PreventRecursiveMutexLock(ImageAccessorBase *iAB)
Prevents a recursive mutex lock by comparing thread ids of competing image accessors.
ImageAccessorBase(ImageConstPointer iP, const ImageDataItem *iDI=nullptr, int OptionFlags=DefaultBehavior)
Checks validity of given parameters from inheriting classes and stores those parameters in member var...
itk::SimpleFastMutexLock m_Mutex
A mutex that allows other ImageAccessors to wait for the represented ImageAccessor.
This struct allows to make ImageAccessors wait for this particular ImageAccessor object.
Internal class for managing references on sub-images.