CustusX  16.12
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxDataReaderWriter.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
33 
34 #include "cxDataReaderWriter.h"
35 
36 #include <sstream>
37 #include <vtkImageData.h>
38 #include <vtkMetaImageReader.h>
39 #include <vtkSmartPointer.h>
40 #include <vtkMetaImageWriter.h>
41 
42 #include <vtkPolyData.h>
43 #include <vtkPolyDataReader.h>
44 #include <vtkPolyDataWriter.h>
45 #include <vtkSTLReader.h>
46 #include <vtkImageChangeInformation.h>
47 #include "vtkMINCImageReader.h"
48 #include "vtkTransform.h"
49 #include "vtkCommand.h"
50 #include <vtkPNGReader.h>
51 
52 #include <QtCore>
53 #include <QDomDocument>
54 #include <QFileInfo>
55 #include <QFile>
56 #include <QTextStream>
57 #include <QDir>
58 
59 #include "cxTransform3D.h"
61 #include "cxLogger.h"
62 #include "cxTypeConversions.h"
63 #include "cxUtilHelpers.h"
64 #include "cxVideoSource.h"
65 #include "cxCustomMetaImage.h"
66 #include "cxConfig.h"
67 
68 #include "cxImageLUT2D.h"
69 #include "cxImageTF3D.h"
70 
71 
72 typedef vtkSmartPointer<class vtkPNGReader> vtkPNGReaderPtr;
73 
74 namespace cx
75 {
76 
77 //---------------------------------------------------------
79 {
80 /* if (!mMutex)
81  mMutex.reset(new QMutex(QMutex::Recursive));
82 
83  mMutex->lock();*/
84 }
86 {
87 // mMutex->unlock();
88 }
89 boost::shared_ptr<QMutex> StaticMutexVtkLocker::mMutex;
90 //---------------------------------------------------------
91 
101 class ErrorObserver: public vtkCommand
102 {
103 public:
105  {
106  }
107  static ErrorObserver* New()
108  {
109  return new ErrorObserver;
110  }
111  virtual void Execute(vtkObject* caller, unsigned long, void* text)
112  {
113  mMessage = QString(reinterpret_cast<char*> (text));
114  }
115  QString mMessage;
116 
117  static bool checkedRead(vtkSmartPointer<vtkAlgorithm> reader, QString filename)
118  {
119  vtkSmartPointer<ErrorObserver> errorObserver = vtkSmartPointer<ErrorObserver>::New();
120  reader->AddObserver("ErrorEvent", errorObserver);
121 
122  {
124  reader->Update();
125  }
126 // ErrorObserver::threadSafeUpdate(reader);
127 
128  if (!errorObserver->mMessage.isEmpty())
129  {
130  reportError("Load of data [" + filename + "] failed with message:\n"
131  + errorObserver->mMessage);
132  return false;
133  }
134  return true;
135  }
136 };
137 
138 //-----
140 {
141  //load the image from file
142  vtkMetaImageReaderPtr reader = vtkMetaImageReaderPtr::New();
143  reader->SetFileName(cstring_cast(filename));
144  reader->ReleaseDataFlagOn();
145 
146  if (!ErrorObserver::checkedRead(reader, filename))
147  return vtkImageDataPtr();
148 
149  vtkImageChangeInformationPtr zeroer = vtkImageChangeInformationPtr::New();
150  zeroer->SetInputConnection(reader->GetOutputPort());
151  zeroer->SetOutputOrigin(0, 0, 0);
152  zeroer->Update();
153  return zeroer->GetOutput();
154 }
155 
156 bool MetaImageReader::readInto(DataPtr data, QString filename)
157 {
158  return this->readInto(boost::dynamic_pointer_cast<Image>(data), filename);
159 }
160 bool MetaImageReader::readInto(ImagePtr image, QString filename)
161 {
162  if (!image)
163  return false;
164 
165  CustomMetaImagePtr customReader = CustomMetaImage::create(filename);
166  Transform3D rMd = customReader->readTransform();
167 
168  vtkImageDataPtr raw = this->loadVtkImageData(filename);
169  if(!raw)
170  return false;
171 
172  image->setVtkImageData(raw);
173 // ImagePtr image(new Image(uid, raw));
174 
175  // RegistrationTransform regTrans(rMd, QFileInfo(filename).lastModified(), "From MHD file");
176  // image->get_rMd_History()->addRegistration(regTrans);
177  image->get_rMd_History()->setRegistration(rMd);
178  image->setModality(customReader->readModality());
179  image->setImageType(customReader->readImageType());
180 
181  bool ok1 = true;
182  bool ok2 = true;
183  double level = customReader->readKey("WindowLevel").toDouble(&ok1);
184  double window = customReader->readKey("WindowWidth").toDouble(&ok2);
185 
186  if (ok1 && ok2)
187  {
188  image->setInitialWindowLevel(window, level);
189  image->resetTransferFunctions();
190  }
191 
192  return true;
193 }
194 
195 //-----
196 DataPtr MetaImageReader::load(const QString& uid, const QString& filename)
197 {
198  ImagePtr image(new Image(uid, vtkImageDataPtr()));
199  this->readInto(image, filename);
200  return image;
201 }
202 
203 void MetaImageReader::saveImage(ImagePtr image, const QString& filename)
204 {
205  vtkMetaImageWriterPtr writer = vtkMetaImageWriterPtr::New();
206  writer->SetInputData(image->getBaseVtkImageData());
207  writer->SetFileDimensionality(3);
208  writer->SetFileName(cstring_cast(filename));
209  QDir().mkpath(QFileInfo(filename).path());
210 
211 // std::cout << "SAVING MHD COMPRESSED " << filename << std::endl;
212 // writer->SetCompression(true);
213  writer->SetCompression(false);
214 // writer->Update(); // caused writing of (null).0 files - not necessary
215  writer->Write();
216 
217  writer = 0;
218 
219  CustomMetaImagePtr customReader = CustomMetaImage::create(filename);
220  customReader->setTransform(image->get_rMd());
221  customReader->setModality(image->getModality());
222  customReader->setImageType(image->getImageType());
223  customReader->setKey("WindowLevel", qstring_cast(image->getInitialWindowLevel()));
224  customReader->setKey("WindowWidth", qstring_cast(image->getInitialWindowWidth()));
225  customReader->setKey("Creator", QString("CustusX_%1").arg(CustusX_VERSION_STRING));
226 }
227 
228 
232 
233 bool PNGImageReader::readInto(DataPtr data, QString filename)
234 {
235  return this->readInto(boost::dynamic_pointer_cast<Image>(data), filename);
236 }
237 
238 bool PNGImageReader::readInto(ImagePtr image, QString filename)
239 {
240  if (!image)
241  return false;
242  vtkImageDataPtr raw = this->loadVtkImageData(filename);
243  if(!raw)
244  return false;
245  image->setVtkImageData(raw);
246  return true;
247 }
248 
249 DataPtr PNGImageReader::load(const QString& uid, const QString& filename)
250 {
251  ImagePtr image(new Image(uid, vtkImageDataPtr()));
252  this->readInto(image, filename);
253  return image;
254 }
255 
257 {
258  vtkPNGReaderPtr pngReader = vtkPNGReaderPtr::New();
259  pngReader->SetFileName(filename.toStdString().c_str());
260  pngReader->Update();
261  return pngReader->GetOutput();
262 }
263 
267 
268 bool PolyDataMeshReader::readInto(DataPtr data, QString filename)
269 {
270  return this->readInto(boost::dynamic_pointer_cast<Mesh>(data), filename);
271 }
272 
273 bool PolyDataMeshReader::readInto(MeshPtr mesh, QString filename)
274 {
275  if (!mesh)
276  return false;
277  vtkPolyDataPtr raw = this->loadVtkPolyData(filename);
278  if(!raw)
279  return false;
280  mesh->setVtkPolyData(raw);
281  return true;
282 }
283 //-----
285 {
286  vtkPolyDataReaderPtr reader = vtkPolyDataReaderPtr::New();
287  reader->SetFileName(cstring_cast(fileName));
288 
289  if (!ErrorObserver::checkedRead(reader, fileName))
290  return vtkPolyDataPtr();
291 
292  vtkPolyDataPtr polyData = reader->GetOutput();
293  return polyData;
294 }
295 
296 DataPtr PolyDataMeshReader::load(const QString& uid, const QString& filename)
297 {
298  MeshPtr mesh(new Mesh(uid));
299  this->readInto(mesh, filename);
300  return mesh;
301 }
302 
303 bool StlMeshReader::readInto(DataPtr data, QString filename)
304 {
305  return this->readInto(boost::dynamic_pointer_cast<Mesh>(data), filename);
306 }
307 
308 bool StlMeshReader::readInto(MeshPtr mesh, QString filename)
309 {
310  if (!mesh)
311  return false;
312  vtkPolyDataPtr raw = this->loadVtkPolyData(filename);
313  if(!raw)
314  return false;
315  mesh->setVtkPolyData(raw);
316  return true;
317 }
318 
319 
321 {
322  vtkSTLReaderPtr reader = vtkSTLReaderPtr::New();
323  reader->SetFileName(cstring_cast(fileName));
324 
325  if (!ErrorObserver::checkedRead(reader, fileName))
326  return vtkPolyDataPtr();
327 
328  vtkPolyDataPtr polyData = reader->GetOutput();
329  return polyData;
330 }
331 
332 DataPtr StlMeshReader::load(const QString& uid, const QString& filename)
333 {
334  MeshPtr mesh(new Mesh(uid));
335  this->readInto(mesh, filename);
336  return mesh;
337 }
338 
340 {
341  mDataReaders.insert(DataReaderPtr(new MetaImageReader()));
342  mDataReaders.insert(DataReaderPtr(new PolyDataMeshReader()));
343  mDataReaders.insert(DataReaderPtr(new StlMeshReader()));
344  mDataReaders.insert(DataReaderPtr(new PNGImageReader()));
345 }
346 
347 DataReaderPtr DataReaderWriter::findReader(const QString& path, const QString& type)
348 {
349  for (DataReadersType::iterator iter = mDataReaders.begin(); iter != mDataReaders.end(); ++iter)
350  {
351  if ((*iter)->canLoad(type, path))
352  return *iter;
353  }
354  return DataReaderPtr();
355 }
356 
358 {
359  DataReaderPtr reader = this->findReader(filename);
360  if (reader)
361  return reader->loadVtkImageData(filename);
362  return vtkImageDataPtr();
363 }
364 
366 {
367  DataReaderPtr reader = this->findReader(filename);
368  if (reader)
369  return reader->loadVtkPolyData(filename);
370  return vtkPolyDataPtr();
371 }
372 
373 QString DataReaderWriter::findDataTypeFromFile(QString filename)
374 {
375  DataReaderPtr reader = this->findReader(filename);
376  if (reader)
377  return reader->canLoadDataType();
378  return "";
379 }
380 
381 void DataReaderWriter::readInto(DataPtr data, QString path)
382 {
383  DataReaderPtr reader = this->findReader(path, data->getType());
384  if (reader)
385  reader->readInto(data, path);
386 
387  if(data)
388  {
389  QFileInfo fileInfo(qstring_cast(path));
390  data->setName(changeExtension(fileInfo.fileName(), ""));
391  data->setFilename(path); // need path even when not set explicitly: nice for testing
392  }
393 
394 }
395 
396 } // namespace cx
397 
398 
QString qstring_cast(const T &val)
void reportError(QString msg)
Definition: cxLogger.cpp:92
A mesh data set.
Definition: cxMesh.h:66
virtual vtkPolyDataPtr loadVtkPolyData(QString filename)
QString findDataTypeFromFile(QString filename)
virtual bool readInto(DataPtr data, QString path)
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
static ErrorObserver * New()
virtual vtkPolyDataPtr loadVtkPolyData(QString filename)
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:48
vtkSmartPointer< vtkImageChangeInformation > vtkImageChangeInformationPtr
Definition: cxImage.cpp:67
cstring_cast_Placeholder cstring_cast(const T &val)
virtual vtkImageDataPtr loadVtkImageData(QString filename)
virtual DataPtr load(const QString &uid, const QString &filename)
boost::shared_ptr< DataReader > DataReaderPtr
vtkPolyDataPtr loadVtkPolyData(QString filename)
boost::shared_ptr< class Data > DataPtr
virtual void Execute(vtkObject *caller, unsigned long, void *text)
vtkSmartPointer< class vtkMetaImageReader > vtkMetaImageReaderPtr
boost::shared_ptr< class CustomMetaImage > CustomMetaImagePtr
vtkSmartPointer< class vtkPolyData > vtkPolyDataPtr
virtual DataPtr load(const QString &uid, const QString &filename)
virtual bool readInto(DataPtr data, QString path)
virtual bool readInto(DataPtr data, QString path)
vtkSmartPointer< class vtkSTLReader > vtkSTLReaderPtr
A volumetric data set.
Definition: cxImage.h:66
vtkSmartPointer< class vtkPNGReader > vtkPNGReaderPtr
vtkSmartPointer< class vtkMetaImageWriter > vtkMetaImageWriterPtr
void saveImage(ImagePtr image, const QString &filename)
virtual DataPtr load(const QString &uid, const QString &filename)
QString changeExtension(QString name, QString ext)
void readInto(DataPtr data, QString path)
virtual vtkImageDataPtr loadVtkImageData(QString filename)
static bool checkedRead(vtkSmartPointer< vtkAlgorithm > reader, QString filename)
Reader for portable network graphics .png files.
vtkSmartPointer< class vtkPolyDataReader > vtkPolyDataReaderPtr
Reader for .vtk files.
virtual bool readInto(DataPtr data, QString path)
boost::shared_ptr< class Mesh > MeshPtr
vtkSmartPointer< class vtkImageData > vtkImageDataPtr
Reader for metaheader .mhd files.
Reader for STL files.
vtkImageDataPtr loadVtkImageData(QString filename)
static CustomMetaImagePtr create(QString filename)
virtual DataPtr load(const QString &uid, const QString &filename)