Fraxinus  16.5.0-fx-rc1
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 "cxPointMetric.h"
69 //#include "cxDistanceMetric.h"
70 //#include "cxPlaneMetric.h"
71 //#include "cxAngleMetric.h"
72 //#include "cxShapedMetric.h"
73 //#include "cxSphereMetric.h"
74 //#include "cxFrameMetric.h"
75 //#include "cxToolMetric.h"
76 
77 #include "cxImageLUT2D.h"
78 #include "cxImageTF3D.h"
79 
80 
81 typedef vtkSmartPointer<class vtkPNGReader> vtkPNGReaderPtr;
82 
83 namespace cx
84 {
85 
86 //---------------------------------------------------------
88 {
89 /* if (!mMutex)
90  mMutex.reset(new QMutex(QMutex::Recursive));
91 
92  mMutex->lock();*/
93 }
95 {
96 // mMutex->unlock();
97 }
98 boost::shared_ptr<QMutex> StaticMutexVtkLocker::mMutex;
99 //---------------------------------------------------------
100 
110 class ErrorObserver: public vtkCommand
111 {
112 public:
114  {
115  }
116  static ErrorObserver* New()
117  {
118  return new ErrorObserver;
119  }
120  virtual void Execute(vtkObject* caller, unsigned long, void* text)
121  {
122  mMessage = QString(reinterpret_cast<char*> (text));
123  }
124  QString mMessage;
125 
126  static bool checkedRead(vtkSmartPointer<vtkAlgorithm> reader, QString filename)
127  {
128  vtkSmartPointer<ErrorObserver> errorObserver = vtkSmartPointer<ErrorObserver>::New();
129  reader->AddObserver("ErrorEvent", errorObserver);
130 
131  {
133  reader->Update();
134  }
135 // ErrorObserver::threadSafeUpdate(reader);
136 
137  if (!errorObserver->mMessage.isEmpty())
138  {
139  reportError("Load of data [" + filename + "] failed with message:\n"
140  + errorObserver->mMessage);
141  return false;
142  }
143  return true;
144  }
145 };
146 
147 //-----
149 {
150  //load the image from file
151  vtkMetaImageReaderPtr reader = vtkMetaImageReaderPtr::New();
152  reader->SetFileName(cstring_cast(filename));
153  reader->ReleaseDataFlagOn();
154 
155  if (!ErrorObserver::checkedRead(reader, filename))
156  return vtkImageDataPtr();
157 
158  vtkImageChangeInformationPtr zeroer = vtkImageChangeInformationPtr::New();
159  zeroer->SetInputConnection(reader->GetOutputPort());
160  zeroer->SetOutputOrigin(0, 0, 0);
161  zeroer->Update();
162  return zeroer->GetOutput();
163 }
164 
165 bool MetaImageReader::readInto(DataPtr data, QString filename)
166 {
167  return this->readInto(boost::dynamic_pointer_cast<Image>(data), filename);
168 }
169 bool MetaImageReader::readInto(ImagePtr image, QString filename)
170 {
171  if (!image)
172  return false;
173 
174  CustomMetaImagePtr customReader = CustomMetaImage::create(filename);
175  Transform3D rMd = customReader->readTransform();
176 
177  vtkImageDataPtr raw = this->loadVtkImageData(filename);
178  if(!raw)
179  return false;
180 
181  image->setVtkImageData(raw);
182 // ImagePtr image(new Image(uid, raw));
183 
184  // RegistrationTransform regTrans(rMd, QFileInfo(filename).lastModified(), "From MHD file");
185  // image->get_rMd_History()->addRegistration(regTrans);
186  image->get_rMd_History()->setRegistration(rMd);
187  image->setModality(customReader->readModality());
188  image->setImageType(customReader->readImageType());
189 
190  bool ok1 = true;
191  bool ok2 = true;
192  double level = customReader->readKey("WindowLevel").toDouble(&ok1);
193  double window = customReader->readKey("WindowWidth").toDouble(&ok2);
194 
195  if (ok1 && ok2)
196  {
197  image->setInitialWindowLevel(window, level);
198  image->resetTransferFunctions();
199  }
200 
201  return true;
202 }
203 
204 //-----
205 DataPtr MetaImageReader::load(const QString& uid, const QString& filename)
206 {
207  ImagePtr image(new Image(uid, vtkImageDataPtr()));
208  this->readInto(image, filename);
209  return image;
210 }
211 
212 void MetaImageReader::saveImage(ImagePtr image, const QString& filename)
213 {
214  vtkMetaImageWriterPtr writer = vtkMetaImageWriterPtr::New();
215  writer->SetInputData(image->getBaseVtkImageData());
216  writer->SetFileDimensionality(3);
217  writer->SetFileName(cstring_cast(filename));
218  QDir().mkpath(QFileInfo(filename).path());
219 
220 // std::cout << "SAVING MHD COMPRESSED " << filename << std::endl;
221 // writer->SetCompression(true);
222  writer->SetCompression(false);
223 // writer->Update(); // caused writing of (null).0 files - not necessary
224  writer->Write();
225 
226  writer = 0;
227 
228  CustomMetaImagePtr customReader = CustomMetaImage::create(filename);
229  customReader->setTransform(image->get_rMd());
230  customReader->setModality(image->getModality());
231  customReader->setImageType(image->getImageType());
232  customReader->setKey("WindowLevel", qstring_cast(image->getInitialWindowLevel()));
233  customReader->setKey("WindowWidth", qstring_cast(image->getInitialWindowWidth()));
234  customReader->setKey("Creator", QString("CustusX_%1").arg(CustusX_VERSION_STRING));
235 }
236 
237 
241 
242 bool PNGImageReader::readInto(DataPtr data, QString filename)
243 {
244  return this->readInto(boost::dynamic_pointer_cast<Image>(data), filename);
245 }
246 
247 bool PNGImageReader::readInto(ImagePtr image, QString filename)
248 {
249  if (!image)
250  return false;
251  vtkImageDataPtr raw = this->loadVtkImageData(filename);
252  if(!raw)
253  return false;
254  image->setVtkImageData(raw);
255  return true;
256 }
257 
258 DataPtr PNGImageReader::load(const QString& uid, const QString& filename)
259 {
260  ImagePtr image(new Image(uid, vtkImageDataPtr()));
261  this->readInto(image, filename);
262  return image;
263 }
264 
266 {
267  vtkPNGReaderPtr pngReader = vtkPNGReaderPtr::New();
268  pngReader->SetFileName(filename.toStdString().c_str());
269  pngReader->Update();
270  return pngReader->GetOutput();
271 }
272 
276 
277 bool PolyDataMeshReader::readInto(DataPtr data, QString filename)
278 {
279  return this->readInto(boost::dynamic_pointer_cast<Mesh>(data), filename);
280 }
281 
282 bool PolyDataMeshReader::readInto(MeshPtr mesh, QString filename)
283 {
284  if (!mesh)
285  return false;
286  vtkPolyDataPtr raw = this->loadVtkPolyData(filename);
287  if(!raw)
288  return false;
289  mesh->setVtkPolyData(raw);
290  return true;
291 }
292 //-----
294 {
295  vtkPolyDataReaderPtr reader = vtkPolyDataReaderPtr::New();
296  reader->SetFileName(cstring_cast(fileName));
297 
298  if (!ErrorObserver::checkedRead(reader, fileName))
299  return vtkPolyDataPtr();
300 
301  vtkPolyDataPtr polyData = reader->GetOutput();
302  return polyData;
303 }
304 
305 DataPtr PolyDataMeshReader::load(const QString& uid, const QString& filename)
306 {
307  MeshPtr mesh(new Mesh(uid));
308  this->readInto(mesh, filename);
309  return mesh;
310 }
311 
312 bool StlMeshReader::readInto(DataPtr data, QString filename)
313 {
314  return this->readInto(boost::dynamic_pointer_cast<Mesh>(data), filename);
315 }
316 
317 bool StlMeshReader::readInto(MeshPtr mesh, QString filename)
318 {
319  if (!mesh)
320  return false;
321  vtkPolyDataPtr raw = this->loadVtkPolyData(filename);
322  if(!raw)
323  return false;
324  mesh->setVtkPolyData(raw);
325  return true;
326 }
327 
328 
330 {
331  vtkSTLReaderPtr reader = vtkSTLReaderPtr::New();
332  reader->SetFileName(cstring_cast(fileName));
333 
334  if (!ErrorObserver::checkedRead(reader, fileName))
335  return vtkPolyDataPtr();
336 
337  vtkPolyDataPtr polyData = reader->GetOutput();
338  return polyData;
339 }
340 
341 DataPtr StlMeshReader::load(const QString& uid, const QString& filename)
342 {
343  MeshPtr mesh(new Mesh(uid));
344  this->readInto(mesh, filename);
345  return mesh;
346 }
347 
349 {
350  mDataReaders.insert(DataReaderPtr(new MetaImageReader()));
351  mDataReaders.insert(DataReaderPtr(new PolyDataMeshReader()));
352  mDataReaders.insert(DataReaderPtr(new StlMeshReader()));
353  mDataReaders.insert(DataReaderPtr(new PNGImageReader()));
354 }
355 
356 DataReaderPtr DataReaderWriter::findReader(const QString& path, const QString& type)
357 {
358  for (DataReadersType::iterator iter = mDataReaders.begin(); iter != mDataReaders.end(); ++iter)
359  {
360  if ((*iter)->canLoad(type, path))
361  return *iter;
362  }
363  return DataReaderPtr();
364 }
365 
367 {
368  DataReaderPtr reader = this->findReader(filename);
369  if (reader)
370  return reader->loadVtkImageData(filename);
371  return vtkImageDataPtr();
372 }
373 
375 {
376  DataReaderPtr reader = this->findReader(filename);
377  if (reader)
378  return reader->loadVtkPolyData(filename);
379  return vtkPolyDataPtr();
380 }
381 
382 QString DataReaderWriter::findDataTypeFromFile(QString filename)
383 {
384  DataReaderPtr reader = this->findReader(filename);
385  if (reader)
386  return reader->canLoadDataType();
387  return "";
388 }
389 
390 void DataReaderWriter::readInto(DataPtr data, QString path)
391 {
392  DataReaderPtr reader = this->findReader(path, data->getType());
393  if (reader)
394  reader->readInto(data, path);
395 
396  if(data)
397  {
398  QFileInfo fileInfo(qstring_cast(path));
399  data->setName(changeExtension(fileInfo.fileName(), ""));
400  data->setFilename(path); // need path even when not set explicitly: nice for testing
401  }
402 
403 }
404 
405 } // namespace cx
406 
407 
QString qstring_cast(const T &val)
void reportError(QString msg)
Definition: cxLogger.cpp:92
A mesh data set.
Definition: cxMesh.h:61
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)