]> Creatis software - cpPlugins.git/blob - plugins/IO/ImageReader.cxx
0402e9e4a865ffb62c358ca053d86e7603fda7d3
[cpPlugins.git] / plugins / IO / ImageReader.cxx
1 #include <plugins/IO/ImageReader.h>
2 #include <plugins/IO/ImageReaderQDialog.h>
3 #include <cpPlugins/DataObjects/Image.h>
4
5 #include <itkImageFileReader.h>
6 #include <itkImageSeriesReader.h>
7
8 #include <itkImageFileReader.hxx>
9 #include <itkImageSeriesReader.hxx>
10 #include <itkConvertPixelBuffer.hxx>
11 #include <itkImageAlgorithm.hxx>
12 #include <itkSimpleDataObjectDecorator.hxx>
13
14 #ifdef cpPlugins_QT4
15
16 #include <QApplication>
17 #include <QFileInfo>
18
19 // -------------------------------------------------------------------------
20 cpPluginsIO::ImageReaderQDialog::
21 ImageReaderQDialog( QWidget* parent )
22   : QFileDialog( parent ),
23     m_ProcessObject( NULL )
24 {
25   this->connect(
26     this, SIGNAL( accepted( ) ), this, SLOT( _dlg_Accepted( ) )
27     );
28   this->setWindowTitle( "Open an(some) image(s)" );
29 }
30
31 // -------------------------------------------------------------------------
32 cpPluginsIO::ImageReaderQDialog::
33 ~ImageReaderQDialog( )
34 {
35 }
36
37 // -------------------------------------------------------------------------
38 void cpPluginsIO::ImageReaderQDialog::
39 setProcessObject( cpPlugins::BaseObjects::ProcessObject* obj )
40 {
41   if( obj == NULL )
42     return;
43   this->m_ProcessObject = obj;
44   auto param = this->m_ProcessObject->GetParameters( );
45   auto extensions = param->GetAcceptedFileExtensions( "FileNames" );
46   auto files = param->GetOpenFileNameList( "FileNames" );
47
48   QStringList filters;
49   if( extensions != "" )
50     filters << extensions.c_str( );
51   filters << "Any file (*)";
52   this->setFileMode( QFileDialog::ExistingFiles );
53   this->setNameFilters( filters );
54   this->setAcceptMode( QFileDialog::AcceptOpen );
55   if( files.size( ) > 0 )
56   {
57     QFileInfo info( files[ 0 ].c_str( ) );
58     this->setDirectory( info.canonicalPath( ) );
59
60   } // fi
61 }
62
63 // -------------------------------------------------------------------------
64 void cpPluginsIO::ImageReaderQDialog::
65 _dlg_Accepted( )
66 {
67   if( this->m_ProcessObject != NULL )
68   {
69     auto param = this->m_ProcessObject->GetParameters( );
70     auto files = this->selectedFiles( );
71     param->ClearOpenFileNameList( "FileNames" );
72     for( auto fIt = files.begin( ); fIt != files.end( ); ++fIt )
73       param->AddToOpenFileNameList( "FileNames", fIt->toStdString( ) );
74
75   } // fi
76 }
77
78 #endif // cpPlugins_QT4
79
80 // -------------------------------------------------------------------------
81 QDialog* cpPluginsIO::ImageReader::
82 CreateQDialog( )
83 {
84 #ifdef cpPlugins_QT4
85   ImageReaderQDialog* dlg = NULL;
86   if( QApplication::instance( ) != NULL )
87   {
88     dlg = new ImageReaderQDialog( );
89     dlg->setProcessObject( this );
90
91   } // fi
92   return( dlg );
93 #else // cpPlugins_QT4
94   return( NULL );
95 #endif // cpPlugins_QT4
96 }
97
98 // -------------------------------------------------------------------------
99 cpPluginsIO::ImageReader::
100 ImageReader( )
101   : Superclass( )
102 {
103   this->_ConfigureOutput< cpPlugins::DataObjects::Image >( "Output" );
104   this->m_Parameters.Clear( );
105   this->m_Parameters.ConfigureAsOpenFileNameList( "FileNames" );
106   this->m_Parameters.SetAcceptedFileExtensions(
107     "FileNames",
108     "Image files (*.bmp *.png *.jpg *.jpeg *.dcm *.mhd *.nhdr *.nrrd *.tiff)"
109     );
110 }
111
112 // -------------------------------------------------------------------------
113 cpPluginsIO::ImageReader::
114 ~ImageReader( )
115 {
116 }
117
118 // -------------------------------------------------------------------------
119 void cpPluginsIO::ImageReader::
120 _GenerateData( )
121 {
122   // Get filenames
123   auto fnames = this->m_Parameters.GetOpenFileNameList( "FileNames" );
124   if( fnames.size( ) >= 1 )
125   {
126     // Guess image properties
127     itk::ImageIOBase::Pointer io =
128       itk::ImageIOFactory::CreateImageIO(
129         fnames[ 0 ].c_str( ),
130         itk::ImageIOFactory::ReadMode
131         );
132     if( io.IsNotNull( ) )
133     {
134       io->SetFileName( fnames[ 0 ] );
135       io->ReadImageInformation( );
136       if( fnames.size( ) >= 1 )
137       {
138         switch( io->GetNumberOfDimensions( ) )
139         {
140         case 1: this->_GD0< 1 >( io ); break;
141         case 2: this->_GD0< 2 >( io ); break;
142         case 3: this->_GD0< 3 >( io ); break;
143         case 4: this->_GD0< 4 >( io ); break;
144         default:
145           this->_Error( "Image dimension not supported." );
146           break;
147         } // hctiws
148
149       } // fi
150     }
151     else
152       this->_Error(
153         std::string( "Could not create an ImageIO for \"" ) +
154         fnames[ 0 ] +
155         std::string( "\"" )
156         );
157   }
158   else
159     this->_Error( "No image(s) given" );
160 }
161
162 // -------------------------------------------------------------------------
163 template< unsigned int _Dim >
164 void cpPluginsIO::ImageReader::
165 _GD0( itk::ImageIOBase* io )
166 {
167   typedef unsigned char  uchar;
168   typedef unsigned short ushort;
169   typedef unsigned int   uint;
170   typedef unsigned long  ulong;
171
172   itk::ImageIOBase::IOComponentType ct = io->GetComponentType( );
173   itk::ImageIOBase::IOPixelType pt = io->GetPixelType( );
174
175   if( pt == itk::ImageIOBase::SCALAR )
176   {
177     switch( ct )
178     {
179     case itk::ImageIOBase::CHAR   : this->_GD1<   char, _Dim >( io ); break;
180     case itk::ImageIOBase::SHORT  : this->_GD1<  short, _Dim >( io ); break;
181     case itk::ImageIOBase::INT    : this->_GD1<    int, _Dim >( io ); break;
182     case itk::ImageIOBase::LONG   : this->_GD1<   long, _Dim >( io ); break;
183     case itk::ImageIOBase::FLOAT  : this->_GD1<  float, _Dim >( io ); break;
184     case itk::ImageIOBase::DOUBLE : this->_GD1< double, _Dim >( io ); break;
185     case itk::ImageIOBase::UCHAR  : this->_GD1<  uchar, _Dim >( io ); break;
186     case itk::ImageIOBase::USHORT : this->_GD1< ushort, _Dim >( io ); break;
187     case itk::ImageIOBase::UINT   : this->_GD1<   uint, _Dim >( io ); break;
188     case itk::ImageIOBase::ULONG  : this->_GD1<  ulong, _Dim >( io ); break;
189     default: this->_Error( "Scalar pixel type not supported." ); break;
190     } // hctiws
191   }
192   else if( pt == itk::ImageIOBase::RGB )
193   {
194     switch( ct )
195     {
196     case itk::ImageIOBase::CHAR   : this->_GD1< itk::RGBPixel<   char >, _Dim >( io ); break;
197     case itk::ImageIOBase::SHORT  : this->_GD1< itk::RGBPixel<  short >, _Dim >( io ); break;
198     case itk::ImageIOBase::INT    : this->_GD1< itk::RGBPixel<    int >, _Dim >( io ); break;
199     case itk::ImageIOBase::LONG   : this->_GD1< itk::RGBPixel<   long >, _Dim >( io ); break;
200     case itk::ImageIOBase::FLOAT  : this->_GD1< itk::RGBPixel<  float >, _Dim >( io ); break;
201     case itk::ImageIOBase::DOUBLE : this->_GD1< itk::RGBPixel< double >, _Dim >( io ); break;
202     case itk::ImageIOBase::UCHAR  : this->_GD1< itk::RGBPixel<  uchar >, _Dim >( io ); break;
203     case itk::ImageIOBase::USHORT : this->_GD1< itk::RGBPixel< ushort >, _Dim >( io ); break;
204     case itk::ImageIOBase::UINT   : this->_GD1< itk::RGBPixel<   uint >, _Dim >( io ); break;
205     case itk::ImageIOBase::ULONG  : this->_GD1< itk::RGBPixel<  ulong >, _Dim >( io ); break;
206     default: this->_Error( "RGB pixel type not supported." ); break;
207     } // hctiws
208   }
209   else if( pt == itk::ImageIOBase::RGBA )
210   {
211     switch( ct )
212     {
213     case itk::ImageIOBase::CHAR   : this->_GD1< itk::RGBAPixel<   char >, _Dim >( io ); break;
214     case itk::ImageIOBase::SHORT  : this->_GD1< itk::RGBAPixel<  short >, _Dim >( io ); break;
215     case itk::ImageIOBase::INT    : this->_GD1< itk::RGBAPixel<    int >, _Dim >( io ); break;
216     case itk::ImageIOBase::LONG   : this->_GD1< itk::RGBAPixel<   long >, _Dim >( io ); break;
217     case itk::ImageIOBase::FLOAT  : this->_GD1< itk::RGBAPixel<  float >, _Dim >( io ); break;
218     case itk::ImageIOBase::DOUBLE : this->_GD1< itk::RGBAPixel< double >, _Dim >( io ); break;
219     case itk::ImageIOBase::UCHAR  : this->_GD1< itk::RGBAPixel<  uchar >, _Dim >( io ); break;
220     case itk::ImageIOBase::USHORT : this->_GD1< itk::RGBAPixel< ushort >, _Dim >( io ); break;
221     case itk::ImageIOBase::UINT   : this->_GD1< itk::RGBAPixel<   uint >, _Dim >( io ); break;
222     case itk::ImageIOBase::ULONG  : this->_GD1< itk::RGBAPixel<  ulong >, _Dim >( io ); break;
223     default: this->_Error( "RGBA pixel type not supported." ); break;
224     } // hctiws
225   }
226   else if( pt == itk::ImageIOBase::COMPLEX )
227   {
228     switch( ct )
229     {
230     case itk::ImageIOBase::FLOAT  : this->_GD1< std::complex< float >, _Dim >( io ); break;
231     case itk::ImageIOBase::DOUBLE : this->_GD1< std::complex< double >, _Dim >( io ); break;
232     default: this->_Error( "Complex pixel type not supported." ); break;
233     } // hctiws
234   }
235   else if( pt == itk::ImageIOBase::COVARIANTVECTOR )
236   {
237     switch( ct )
238     {
239     case itk::ImageIOBase::FLOAT  : this->_GD1< itk::CovariantVector< float, _Dim >, _Dim >( io ); break;
240     case itk::ImageIOBase::DOUBLE : this->_GD1< itk::CovariantVector< double, _Dim >, _Dim >( io ); break;
241     default: this->_Error( "CovariantVector pixel type not supported." ); break;
242     } // hctiws
243   }
244   else if( pt == itk::ImageIOBase::POINT )
245   {
246     switch( ct )
247     {
248     case itk::ImageIOBase::FLOAT  : this->_GD1< itk::Point< float, _Dim >, _Dim >( io ); break;
249     case itk::ImageIOBase::DOUBLE : this->_GD1< itk::Point< double, _Dim >, _Dim >( io ); break;
250     default: this->_Error( "Point pixel type not supported." ); break;
251     } // hctiws
252   }
253   else if( pt == itk::ImageIOBase::VECTOR )
254   {
255     switch( ct )
256     {
257     case itk::ImageIOBase::FLOAT  : this->_GD1< itk::Vector< float, _Dim >, _Dim >( io ); break;
258     case itk::ImageIOBase::DOUBLE : this->_GD1< itk::Vector< double, _Dim >, _Dim >( io ); break;
259     default: this->_Error( "Vector pixel type not supported." ); break;
260     } // hctiws
261   }
262   else if( pt == itk::ImageIOBase::SYMMETRICSECONDRANKTENSOR )
263   {
264     switch( ct )
265     {
266     case itk::ImageIOBase::FLOAT  : this->_GD1< itk::SymmetricSecondRankTensor< float, _Dim >, _Dim >( io ); break;
267     case itk::ImageIOBase::DOUBLE : this->_GD1< itk::SymmetricSecondRankTensor< double, _Dim >, _Dim >( io ); break;
268     default: this->_Error( "SymmetricSecondRankTensor pixel type not supported." ); break;
269     } // hctiws
270   }
271   else if( pt == itk::ImageIOBase::DIFFUSIONTENSOR3D )
272   {
273     if( _Dim == 3 )
274     {
275       switch( ct )
276       {
277       case itk::ImageIOBase::FLOAT  : this->_GD1< itk::DiffusionTensor3D< float >, 3 >( io ); break;
278       case itk::ImageIOBase::DOUBLE : this->_GD1< itk::DiffusionTensor3D< double >, 3 >( io ); break;
279       default: this->_Error( "DiffusionTensor3D pixel type not supported." ); break;
280       } // hctiws
281     }
282     else
283       this->_Error( "DiffusionTensor3D dimension not supported." );
284   }
285   else if( pt == itk::ImageIOBase::MATRIX )
286   {
287     switch( ct )
288     {
289     case itk::ImageIOBase::FLOAT  : this->_GD1< itk::Matrix< float, _Dim, _Dim >, _Dim >( io ); break;
290     case itk::ImageIOBase::DOUBLE : this->_GD1< itk::Matrix< double, _Dim, _Dim >, _Dim >( io ); break;
291     default: this->_Error( "Matrix pixel type not supported." ); break;
292     } // hctiws
293   }
294   else if( pt == itk::ImageIOBase::OFFSET )
295   {
296     this->_GD1< itk::Offset< _Dim >, _Dim >( io );
297   }
298   else if( pt == itk::ImageIOBase::FIXEDARRAY )
299   {
300     switch( ct )
301     {
302     case itk::ImageIOBase::CHAR   : this->_GD1< itk::FixedArray<   char, _Dim >, _Dim >( io ); break;
303     case itk::ImageIOBase::SHORT  : this->_GD1< itk::FixedArray<  short, _Dim >, _Dim >( io ); break;
304     case itk::ImageIOBase::INT    : this->_GD1< itk::FixedArray<    int, _Dim >, _Dim >( io ); break;
305     case itk::ImageIOBase::LONG   : this->_GD1< itk::FixedArray<   long, _Dim >, _Dim >( io ); break;
306     case itk::ImageIOBase::FLOAT  : this->_GD1< itk::FixedArray<  float, _Dim >, _Dim >( io ); break;
307     case itk::ImageIOBase::DOUBLE : this->_GD1< itk::FixedArray< double, _Dim >, _Dim >( io ); break;
308     case itk::ImageIOBase::UCHAR  : this->_GD1< itk::FixedArray<  uchar, _Dim >, _Dim >( io ); break;
309     case itk::ImageIOBase::USHORT : this->_GD1< itk::FixedArray< ushort, _Dim >, _Dim >( io ); break;
310     case itk::ImageIOBase::UINT   : this->_GD1< itk::FixedArray<   uint, _Dim >, _Dim >( io ); break;
311     case itk::ImageIOBase::ULONG  : this->_GD1< itk::FixedArray<  ulong, _Dim >, _Dim >( io ); break;
312     default: this->_Error( "Scalar pixel type not supported." ); break;
313     } // hctiws
314   }
315   else
316     this->_Error( "Image pixel type not yet supported." );
317 }
318
319 // -------------------------------------------------------------------------
320 template< class _TPixel, unsigned int _Dim >
321 void cpPluginsIO::ImageReader::
322 _GD1( itk::ImageIOBase* io )
323 {
324   typedef itk::Image< _TPixel, _Dim > _TImage;
325
326   // Get filenames
327   auto fnames = this->m_Parameters.GetOpenFileNameList( "FileNames" );
328   if( fnames.size( ) == 1 )
329   {
330     auto f = this->_CreateITK< itk::ImageFileReader< _TImage > >( );
331     f->SetFileName( fnames[ 0 ] );
332     f->SetImageIO( io );
333     try
334     {
335       f->Update( );
336       this->GetOutput( "Output" )->SetITK( f->GetOutput( ) );
337     }
338     catch( itk::ExceptionObject& err )
339     {
340       this->_Error( err.GetDescription( ) );
341
342     } // yrt
343   }
344   else // if( fnames.size( ) > 1 )
345   {
346     auto f = this->_CreateITK< itk::ImageSeriesReader< _TImage > >( );
347     for( auto i = fnames.begin( ); i != fnames.end( ); ++i )
348       f->AddFileName( *i );
349     f->SetImageIO( io );
350     try
351     {
352       f->Update( );
353       this->GetOutput( "Output" )->SetITK( f->GetOutput( ) );
354     }
355     catch( itk::ExceptionObject& err )
356     {
357       this->_Error( err.GetDescription( ) );
358
359     } // yrt
360
361   } // fi
362 }
363
364 // eof - $RCSfile$