Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkCoreActivator.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 "mitkCoreActivator.h"
14 
15 // File IO
18 #include <mitkIOMimeTypes.h>
19 #include <mitkIOUtil.h>
20 #include <mitkImageVtkLegacyIO.h>
21 #include <mitkImageVtkXmlIO.h>
22 #include <mitkItkImageIO.h>
23 #include <mitkMimeTypeProvider.h>
26 #include <mitkRawImageFileReader.h>
27 #include <mitkSurfaceStlIO.h>
28 #include <mitkSurfaceVtkLegacyIO.h>
29 #include <mitkSurfaceVtkXmlIO.h>
30 
32 #include <mitkFileWriter.h>
33 
34 #include <itkGDCMImageIO.h>
35 #include <itkNiftiImageIO.h>
36 
37 // Micro Services
38 #include <usGetModuleContext.h>
39 #include <usModule.h>
40 #include <usModuleActivator.h>
41 #include <usModuleContext.h>
42 #include <usModuleEvent.h>
43 #include <usModuleInitialization.h>
44 #include <usModuleResource.h>
45 #include <usModuleResourceStream.h>
46 #include <usModuleSettings.h>
47 #include <usServiceTracker.h>
48 
49 // ITK "injects" static initialization code for IO factories
50 // via the itkImageIOFactoryRegisterManager.h header (which
51 // is generated in the application library build directory).
52 // To ensure that the code is called *before* the CppMicroServices
53 // static initialization code (which triggers the Activator::Start
54 // method), we include the ITK header here.
56 
57 void HandleMicroServicesMessages(us::MsgType type, const char *msg)
58 {
59  switch (type)
60  {
61  case us::DebugMsg:
62  MITK_DEBUG << msg;
63  break;
64  case us::InfoMsg:
65  MITK_INFO << msg;
66  break;
67  case us::WarningMsg:
68  MITK_WARN << msg;
69  break;
70  case us::ErrorMsg:
71  MITK_ERROR << msg;
72  break;
73  }
74 }
75 
76 void AddMitkAutoLoadPaths(const std::string &programPath)
77 {
79 #ifdef __APPLE__
80  // Walk up three directories since that is where the .dylib files are located
81  // for build trees.
82  std::string additionalPath = programPath;
83  bool addPath = true;
84  for (int i = 0; i < 3; ++i)
85  {
86  std::size_t index = additionalPath.find_last_of('/');
87  if (index != std::string::npos)
88  {
89  additionalPath = additionalPath.substr(0, index);
90  }
91  else
92  {
93  addPath = false;
94  break;
95  }
96  }
97  if (addPath)
98  {
100  }
101 #endif
102 }
103 
104 class FixedNiftiImageIO : public itk::NiftiImageIO
105 {
106 public:
108  typedef FixedNiftiImageIO Self;
109  typedef itk::NiftiImageIO Superclass;
110  typedef itk::SmartPointer<Self> Pointer;
111 
113  itkNewMacro(Self)
114 
115 
116  itkTypeMacro(FixedNiftiImageIO, Superclass)
117 
118  bool SupportsDimension(unsigned long dim) override
119  {
120  return dim > 1 && dim < 5;
121  }
122 };
123 
124 void MitkCoreActivator::Load(us::ModuleContext *context)
125 {
126  // Handle messages from CppMicroServices
128 
129  this->m_Context = context;
130 
131  // Add the current application directory to the auto-load paths.
132  // This is useful for third-party executables.
133  std::string programPath = mitk::IOUtil::GetProgramPath();
134  if (programPath.empty())
135  {
136  MITK_WARN << "Could not get the program path.";
137  }
138  else
139  {
140  AddMitkAutoLoadPaths(programPath);
141  }
142 
143  // m_RenderingManager = mitk::RenderingManager::New();
144  // context->RegisterService<mitk::RenderingManager>(renderingManager.GetPointer());
145  m_PlanePositionManager.reset(new mitk::PlanePositionManagerService);
146  context->RegisterService<mitk::PlanePositionManagerService>(m_PlanePositionManager.get());
147 
148  m_PropertyAliases.reset(new mitk::PropertyAliases);
149  context->RegisterService<mitk::IPropertyAliases>(m_PropertyAliases.get());
150 
151  m_PropertyDescriptions.reset(new mitk::PropertyDescriptions);
152  context->RegisterService<mitk::IPropertyDescriptions>(m_PropertyDescriptions.get());
153 
154  m_PropertyExtensions.reset(new mitk::PropertyExtensions);
155  context->RegisterService<mitk::IPropertyExtensions>(m_PropertyExtensions.get());
156 
157  m_PropertyFilters.reset(new mitk::PropertyFilters);
158  context->RegisterService<mitk::IPropertyFilters>(m_PropertyFilters.get());
159 
160  m_PropertyPersistence.reset(new mitk::PropertyPersistence);
161  context->RegisterService<mitk::IPropertyPersistence>(m_PropertyPersistence.get());
162 
163  m_PropertyRelations.reset(new mitk::PropertyRelations);
164  context->RegisterService<mitk::IPropertyRelations>(m_PropertyRelations.get());
165 
166  m_MimeTypeProvider.reset(new mitk::MimeTypeProvider);
167  m_MimeTypeProvider->Start();
168  m_MimeTypeProviderReg = context->RegisterService<mitk::IMimeTypeProvider>(m_MimeTypeProvider.get());
169 
170  this->RegisterDefaultMimeTypes();
171  this->RegisterItkReaderWriter();
172  this->RegisterVtkReaderWriter();
173 
174  // Add custom Reader / Writer Services
175  m_FileReaders.push_back(new mitk::PointSetReaderService());
176  m_FileWriters.push_back(new mitk::PointSetWriterService());
177  m_FileReaders.push_back(new mitk::GeometryDataReaderService());
178  m_FileWriters.push_back(new mitk::GeometryDataWriterService());
179  m_FileReaders.push_back(new mitk::RawImageFileReaderService());
180 
181  /*
182  There IS an option to exchange ALL vtkTexture instances against vtkNeverTranslucentTextureFactory.
183  This code is left here as a reminder, just in case we might need to do that some time.
184 
185  vtkNeverTranslucentTextureFactory* textureFactory = vtkNeverTranslucentTextureFactory::New();
186  vtkObjectFactory::RegisterFactory( textureFactory );
187  textureFactory->Delete();
188  */
189 
190  this->RegisterLegacyWriter();
191 }
192 
193 void MitkCoreActivator::Unload(us::ModuleContext *)
194 {
195  for (auto &elem : m_FileReaders)
196  {
197  delete elem;
198  }
199 
200  for (auto &elem : m_FileWriters)
201  {
202  delete elem;
203  }
204 
205  for (auto &elem : m_FileIOs)
206  {
207  delete elem;
208  }
209 
210  for (auto &elem : m_LegacyWriters)
211  {
212  delete elem;
213  }
214 
215  // The mitk::ModuleContext* argument of the Unload() method
216  // will always be 0 for the Mitk library. It makes no sense
217  // to use it at this stage anyway, since all libraries which
218  // know about the module system have already been unloaded.
219 
220  // we need to close the internal service tracker of the
221  // MimeTypeProvider class here. Otherwise it
222  // would hold on to the ModuleContext longer than it is
223  // actually valid.
224  m_MimeTypeProviderReg.Unregister();
225  m_MimeTypeProvider->Stop();
226 
227  for (std::vector<mitk::CustomMimeType *>::const_iterator mimeTypeIter = m_DefaultMimeTypes.begin(),
228  iterEnd = m_DefaultMimeTypes.end();
229  mimeTypeIter != iterEnd;
230  ++mimeTypeIter)
231  {
232  delete *mimeTypeIter;
233  }
234 }
235 
236 void MitkCoreActivator::RegisterDefaultMimeTypes()
237 {
238  // Register some default mime-types
239 
240  std::vector<mitk::CustomMimeType *> mimeTypes = mitk::IOMimeTypes::Get();
241  for (std::vector<mitk::CustomMimeType *>::const_iterator mimeTypeIter = mimeTypes.begin(), iterEnd = mimeTypes.end();
242  mimeTypeIter != iterEnd;
243  ++mimeTypeIter)
244  {
245  m_DefaultMimeTypes.push_back(*mimeTypeIter);
246  m_Context->RegisterService(m_DefaultMimeTypes.back());
247  }
248 }
249 
250 void MitkCoreActivator::RegisterItkReaderWriter()
251 {
252  std::list<itk::LightObject::Pointer> allobjects = itk::ObjectFactoryBase::CreateAllInstance("itkImageIOBase");
253 
254  for (auto &allobject : allobjects)
255  {
256  auto *io = dynamic_cast<itk::ImageIOBase *>(allobject.GetPointer());
257 
258  // NiftiImageIO does not provide a correct "SupportsDimension()" methods
259  // and the supported read/write extensions are not ordered correctly
260  if (dynamic_cast<itk::NiftiImageIO *>(io))
261  continue;
262 
263  // Use a custom mime-type for GDCMImageIO below
264  if (dynamic_cast<itk::GDCMImageIO *>(allobject.GetPointer()))
265  {
266  // MITK provides its own DICOM reader (which internally uses GDCMImageIO).
267  continue;
268  }
269 
270  if (io)
271  {
272  m_FileIOs.push_back(new mitk::ItkImageIO(io));
273  }
274  else
275  {
276  MITK_WARN << "Error ImageIO factory did not return an ImageIOBase: " << (allobject)->GetNameOfClass();
277  }
278  }
279 
280  FixedNiftiImageIO::Pointer itkNiftiIO = FixedNiftiImageIO::New();
281  mitk::ItkImageIO *niftiIO = new mitk::ItkImageIO(mitk::IOMimeTypes::NIFTI_MIMETYPE(), itkNiftiIO.GetPointer(), 0);
282  m_FileIOs.push_back(niftiIO);
283 }
284 
285 void MitkCoreActivator::RegisterVtkReaderWriter()
286 {
287  m_FileIOs.push_back(new mitk::SurfaceVtkXmlIO());
288  m_FileIOs.push_back(new mitk::SurfaceStlIO());
289  m_FileIOs.push_back(new mitk::SurfaceVtkLegacyIO());
290 
291  m_FileIOs.push_back(new mitk::ImageVtkXmlIO());
292  m_FileIOs.push_back(new mitk::ImageVtkLegacyIO());
293 }
294 
295 void MitkCoreActivator::RegisterLegacyWriter()
296 {
297  std::list<itk::LightObject::Pointer> allobjects = itk::ObjectFactoryBase::CreateAllInstance("IOWriter");
298 
299  for (auto i = allobjects.begin(); i != allobjects.end(); ++i)
300  {
301  mitk::FileWriter::Pointer io = dynamic_cast<mitk::FileWriter *>(i->GetPointer());
302  if (io)
303  {
304  std::string description = std::string("Legacy ") + io->GetNameOfClass() + " Writer";
305  mitk::IFileWriter *writer = new mitk::LegacyFileWriterService(io, description);
306  m_LegacyWriters.push_back(writer);
307  }
308  else
309  {
310  MITK_ERROR << "Error IOWriter override is not of type mitk::FileWriter: " << (*i)->GetNameOfClass() << std::endl;
311  }
312  }
313 }
314 
316 
317 // Call CppMicroservices initialization code at the end of the file.
318 // This especially ensures that VTK object factories have already
319 // been registered (VTK initialization code is injected by implicitly
320 // include VTK header files at the top of this file).
Interface of property relations service.
Interface of property aliases service.
static std::vector< CustomMimeType * > Get()
#define MITK_INFO
Definition: mitkLogMacros.h:18
void Load(us::ModuleContext *context) override
static void AddAutoLoadPath(const std::string &path)
#define MITK_ERROR
Definition: mitkLogMacros.h:20
#define MITK_DEBUG
Definition: mitkLogMacros.h:22
Interface of property extensions service.
#define US_INITIALIZE_MODULE
Creates initialization code for a module.
void Unload(us::ModuleContext *) override
Interface of property descriptions service.
#define MITK_WARN
Definition: mitkLogMacros.h:19
The IMimeTypeProvider service interface allows to query all registered mime types.
Interface class of writers that write data to files.
static CustomMimeType NIFTI_MIMETYPE()
static std::string GetProgramPath()
Definition: mitkIOUtil.cpp:356
Interface of property persistence service.
MsgHandler installMsgHandler(MsgHandler h)
Definition: usUtils.cpp:263
void HandleMicroServicesMessages(us::MsgType type, const char *msg)
Interface of property filters service.
void AddMitkAutoLoadPaths(const std::string &programPath)
The common interface of all MITK file writers.
#define US_EXPORT_MODULE_ACTIVATOR(_activator_type)
Export a module activator class.