1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkImageReader2Factory.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkImageReader2Factory.h"
16 
17 #include "vtkBMPReader.h"
18 #include "vtkGESignaReader.h"
19 #include "vtkHDRReader.h"
20 #include "vtkImageReader2.h"
21 #include "vtkImageReader2Collection.h"
22 #include "vtkJPEGReader.h"
23 #include "vtkMetaImageReader.h"
24 #include "vtkNew.h"
25 #include "vtkObjectFactory.h"
26 #include "vtkObjectFactoryCollection.h"
27 #include "vtkPNGReader.h"
28 #include "vtkPNMReader.h"
29 #include "vtkSLCReader.h"
30 #include "vtkTGAReader.h"
31 #include "vtkTIFFReader.h"
32 
33 // Destroying the prototype readers requires information keys.
34 // Include the manager here to make sure the keys are not destroyed
35 // until after the AvailableReaders singleton has been destroyed.
36 #include "vtkFilteringInformationKeyManager.h"
37 
38 #include <sstream>
39 
40 vtkStandardNewMacro(vtkImageReader2Factory);
41 
42 //----------------------------------------------------------------------------
43 class vtkImageReader2FactoryCleanup
44 {
45 public:
Use()46   inline void Use() {}
~vtkImageReader2FactoryCleanup()47   ~vtkImageReader2FactoryCleanup()
48   {
49     if (vtkImageReader2Factory::AvailableReaders)
50     {
51       vtkImageReader2Factory::AvailableReaders->Delete();
52       vtkImageReader2Factory::AvailableReaders = nullptr;
53     }
54   }
55 };
56 static vtkImageReader2FactoryCleanup vtkImageReader2FactoryCleanupGlobal;
57 
58 //----------------------------------------------------------------------------
59 vtkImageReader2Collection* vtkImageReader2Factory::AvailableReaders;
60 
61 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)62 void vtkImageReader2Factory::PrintSelf(ostream& os, vtkIndent indent)
63 {
64   this->Superclass::PrintSelf(os, indent);
65   os << indent << "Available Readers : ";
66   if (AvailableReaders)
67   {
68     AvailableReaders->PrintSelf(os, indent);
69   }
70   else
71   {
72     os << "None.";
73   }
74 }
75 
76 //----------------------------------------------------------------------------
RegisterReader(vtkImageReader2 * r)77 void vtkImageReader2Factory::RegisterReader(vtkImageReader2* r)
78 {
79   vtkImageReader2Factory::InitializeReaders();
80   AvailableReaders->AddItem(r);
81 }
82 
83 //----------------------------------------------------------------------------
CreateImageReader2(const char * path)84 vtkImageReader2* vtkImageReader2Factory::CreateImageReader2(const char* path)
85 {
86   vtkImageReader2Factory::InitializeReaders();
87   vtkImageReader2* ret;
88   vtkNew<vtkCollection> collection;
89   vtkObjectFactory::CreateAllInstance("vtkImageReaderObject", collection);
90   // first try the current registered object factories to see
91   // if one of them can
92   for (collection->InitTraversal(); vtkObject* object = collection->GetNextItemAsObject();)
93   {
94     ret = vtkImageReader2::SafeDownCast(object);
95     if (ret && ret->CanReadFile(path))
96     {
97       return ret;
98     }
99   }
100 
101   // Then try all available readers
102   vtkCollectionSimpleIterator sit;
103   for (vtkImageReader2Factory::AvailableReaders->InitTraversal(sit);
104        (ret = vtkImageReader2Factory::AvailableReaders->GetNextImageReader2(sit));)
105   {
106     if (ret->CanReadFile(path))
107     {
108       // like a new call
109       return ret->NewInstance();
110     }
111   }
112   return nullptr;
113 }
114 
115 //----------------------------------------------------------------------------
CreateImageReader2FromExtension(const char * extension)116 vtkImageReader2* vtkImageReader2Factory::CreateImageReader2FromExtension(const char* extension)
117 {
118   vtkImageReader2Factory::InitializeReaders();
119   vtkImageReader2* ret;
120   vtkNew<vtkCollection> collection;
121   vtkObjectFactory::CreateAllInstance("vtkImageReaderObject", collection);
122 
123   // first try the current registered object factories to see
124   // if one of them can
125   for (collection->InitTraversal(); vtkObject* object = collection->GetNextItemAsObject();)
126   {
127     ret = vtkImageReader2::SafeDownCast(object);
128     if (ret)
129     {
130       const char* extensions = ret->GetFileExtensions();
131       if (vtkImageReader2Factory::CheckExtensionIsInExtensions(extension, extensions))
132       {
133         return ret;
134       }
135     }
136   }
137 
138   // Then try all available readers
139   vtkCollectionSimpleIterator sit;
140   for (vtkImageReader2Factory::AvailableReaders->InitTraversal(sit);
141        (ret = vtkImageReader2Factory::AvailableReaders->GetNextImageReader2(sit));)
142   {
143     const char* extensions = ret->GetFileExtensions();
144     if (vtkImageReader2Factory::CheckExtensionIsInExtensions(extension, extensions))
145     {
146       return ret->NewInstance();
147     }
148   }
149   return nullptr;
150 }
151 
152 //----------------------------------------------------------------------------
CheckExtensionIsInExtensions(const char * extension,const char * extensions)153 bool vtkImageReader2Factory::CheckExtensionIsInExtensions(
154   const char* extension, const char* extensions)
155 {
156   std::istringstream iss(extensions);
157   std::string localExtension;
158   while (iss >> localExtension)
159   {
160     if (localExtension == std::string(extension) || localExtension == "." + std::string(extension))
161     {
162       return true;
163     }
164   }
165   return false;
166 }
167 
168 //----------------------------------------------------------------------------
InitializeReaders()169 void vtkImageReader2Factory::InitializeReaders()
170 {
171   if (vtkImageReader2Factory::AvailableReaders)
172   {
173     return;
174   }
175   vtkImageReader2FactoryCleanupGlobal.Use();
176   vtkImageReader2Factory::AvailableReaders = vtkImageReader2Collection::New();
177   vtkImageReader2* reader;
178 
179   vtkImageReader2Factory::AvailableReaders->AddItem((reader = vtkPNGReader::New()));
180   reader->Delete();
181   vtkImageReader2Factory::AvailableReaders->AddItem((reader = vtkPNMReader::New()));
182   reader->Delete();
183   vtkImageReader2Factory::AvailableReaders->AddItem((reader = vtkTIFFReader::New()));
184   reader->Delete();
185   vtkImageReader2Factory::AvailableReaders->AddItem((reader = vtkBMPReader::New()));
186   reader->Delete();
187   vtkImageReader2Factory::AvailableReaders->AddItem((reader = vtkSLCReader::New()));
188   reader->Delete();
189   vtkImageReader2Factory::AvailableReaders->AddItem((reader = vtkHDRReader::New()));
190   reader->Delete();
191   vtkImageReader2Factory::AvailableReaders->AddItem((reader = vtkJPEGReader::New()));
192   reader->Delete();
193   vtkImageReader2Factory::AvailableReaders->AddItem((reader = vtkGESignaReader::New()));
194   reader->Delete();
195   vtkImageReader2Factory::AvailableReaders->AddItem((reader = vtkMetaImageReader::New()));
196   reader->Delete();
197   vtkImageReader2Factory::AvailableReaders->AddItem((reader = vtkTGAReader::New()));
198   reader->Delete();
199 }
200 
201 //----------------------------------------------------------------------------
GetRegisteredReaders(vtkImageReader2Collection * collection)202 void vtkImageReader2Factory::GetRegisteredReaders(vtkImageReader2Collection* collection)
203 {
204   vtkImageReader2Factory::InitializeReaders();
205   // get all dynamic readers
206   vtkObjectFactory::CreateAllInstance("vtkImageReaderObject", collection);
207   // get the current registered readers
208   vtkImageReader2* ret;
209   vtkCollectionSimpleIterator sit;
210   for (vtkImageReader2Factory::AvailableReaders->InitTraversal(sit);
211        (ret = vtkImageReader2Factory::AvailableReaders->GetNextImageReader2(sit));)
212   {
213     collection->AddItem(ret);
214   }
215 }
216