1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkImageReader2.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 "vtkImageReader2.h"
16 
17 #include "vtkByteSwap.h"
18 #include "vtkDataArray.h"
19 #include "vtkImageData.h"
20 #include "vtkInformation.h"
21 #include "vtkInformationVector.h"
22 #include "vtkObjectFactory.h"
23 #include "vtkPointData.h"
24 #include "vtkErrorCode.h"
25 #include "vtkStreamingDemandDrivenPipeline.h"
26 #include "vtkStringArray.h"
27 
28 #include <sys/stat.h>
29 
30 vtkStandardNewMacro(vtkImageReader2);
31 
32 #ifdef read
33 #undef read
34 #endif
35 
36 #ifdef close
37 #undef close
38 #endif
39 
40 //----------------------------------------------------------------------------
vtkImageReader2()41 vtkImageReader2::vtkImageReader2()
42 {
43   this->FilePrefix = NULL;
44   this->FilePattern = new char[strlen("%s.%d") + 1];
45   strcpy (this->FilePattern, "%s.%d");
46   this->File = NULL;
47 
48   this->DataScalarType = VTK_SHORT;
49   this->NumberOfScalarComponents = 1;
50 
51   this->DataOrigin[0] = this->DataOrigin[1] = this->DataOrigin[2] = 0.0;
52 
53   this->DataSpacing[0] = this->DataSpacing[1] = this->DataSpacing[2] = 1.0;
54 
55   this->DataExtent[0] = this->DataExtent[2] = this->DataExtent[4] = 0;
56   this->DataExtent[1] = this->DataExtent[3] = this->DataExtent[5] = 0;
57 
58   this->DataIncrements[0] = this->DataIncrements[1] =
59   this->DataIncrements[2] = this->DataIncrements[3] = 1;
60 
61   this->FileNames = NULL;
62 
63   this->FileName = NULL;
64   this->InternalFileName = NULL;
65 
66   this->MemoryBuffer = NULL;
67   this->MemoryBufferLength = 0;
68 
69   this->HeaderSize = 0;
70   this->ManualHeaderSize = 0;
71 
72   this->FileNameSliceOffset = 0;
73   this->FileNameSliceSpacing = 1;
74 
75   // Left over from short reader
76   this->SwapBytes = 0;
77   this->FileLowerLeft = 0;
78   this->FileDimensionality = 2;
79   this->SetNumberOfInputPorts(0);
80 }
81 
82 //----------------------------------------------------------------------------
~vtkImageReader2()83 vtkImageReader2::~vtkImageReader2()
84 {
85   if (this->File)
86     {
87     this->File->close();
88     delete this->File;
89     this->File = NULL;
90     }
91 
92   if (this->FileNames)
93     {
94     this->FileNames->Delete();
95     this->FileNames = NULL;
96     }
97   delete [] this->FileName;
98   this->FileName = NULL;
99   delete [] this->FilePrefix;
100   this->FilePrefix = NULL;
101   delete [] this->FilePattern;
102   this->FilePattern = NULL;
103   delete [] this->InternalFileName;
104   this->InternalFileName = NULL;
105 }
106 
107 //----------------------------------------------------------------------------
108 // This function sets the name of the file.
ComputeInternalFileName(int slice)109 void vtkImageReader2::ComputeInternalFileName(int slice)
110 {
111   // delete any old filename
112   delete [] this->InternalFileName;
113   this->InternalFileName = NULL;
114 
115   if (!this->FileName && !this->FilePattern && !this->FileNames)
116     {
117     vtkErrorMacro(<<"Either a FileName, FileNames, or FilePattern"
118                   <<" must be specified.");
119     return;
120     }
121 
122   // make sure we figure out a filename to open
123   if (this->FileNames)
124     {
125     const char *filename = this->FileNames->GetValue(slice);
126     this->InternalFileName = new char [strlen(filename) + 10];
127     sprintf(this->InternalFileName,"%s",filename);
128     }
129   else if (this->FileName)
130     {
131     this->InternalFileName = new char [strlen(this->FileName) + 10];
132     sprintf(this->InternalFileName,"%s",this->FileName);
133     }
134   else
135     {
136     int slicenum =
137       slice * this->FileNameSliceSpacing
138       + this->FileNameSliceOffset;
139     if (this->FilePrefix && this->FilePattern)
140       {
141       this->InternalFileName = new char [strlen(this->FilePrefix) +
142                                         strlen(this->FilePattern) + 10];
143       sprintf (this->InternalFileName, this->FilePattern,
144                this->FilePrefix, slicenum);
145       }
146     else if (this->FilePattern)
147       {
148       this->InternalFileName = new char [strlen(this->FilePattern) + 10];
149       int len = static_cast<int>(strlen(this->FilePattern));
150       int hasPercentS = 0;
151       for(int i =0; i < len-1; ++i)
152         {
153         if(this->FilePattern[i] == '%' && this->FilePattern[i+1] == 's')
154           {
155           hasPercentS = 1;
156           break;
157           }
158         }
159       if(hasPercentS)
160         {
161         sprintf (this->InternalFileName, this->FilePattern, "", slicenum);
162         }
163       else
164         {
165         sprintf (this->InternalFileName, this->FilePattern, slicenum);
166         }
167       }
168     else
169       {
170       delete [] this->InternalFileName;
171       this->InternalFileName = 0;
172       }
173     }
174 }
175 
176 
177 //----------------------------------------------------------------------------
178 // This function sets the name of the file.
SetFileName(const char * name)179 void vtkImageReader2::SetFileName(const char *name)
180 {
181   if ( this->FileName && name && (!strcmp(this->FileName,name)))
182     {
183     return;
184     }
185   if (!name && !this->FileName)
186     {
187     return;
188     }
189   delete [] this->FileName;
190   this->FileName = NULL;
191   if (name)
192     {
193     this->FileName = new char[strlen(name) + 1];
194     strcpy(this->FileName, name);
195 
196     delete [] this->FilePrefix;
197     this->FilePrefix = NULL;
198     if (this->FileNames)
199       {
200       this->FileNames->Delete();
201       this->FileNames = NULL;
202       }
203     }
204 
205   this->Modified();
206 }
207 
208 //----------------------------------------------------------------------------
209 // This function sets an array containing file names
SetFileNames(vtkStringArray * filenames)210 void vtkImageReader2::SetFileNames(vtkStringArray *filenames)
211 {
212   if (filenames == this->FileNames)
213     {
214     return;
215     }
216   if (this->FileNames)
217     {
218     this->FileNames->Delete();
219     this->FileNames = 0;
220     }
221   if (filenames)
222     {
223     this->FileNames = filenames;
224     this->FileNames->Register(this);
225     if (this->FileNames->GetNumberOfValues() > 0)
226       {
227       this->DataExtent[4] = 0;
228       this->DataExtent[5] = this->FileNames->GetNumberOfValues() - 1;
229       }
230     delete [] this->FilePrefix;
231     this->FilePrefix = NULL;
232     delete [] this->FileName;
233     this->FileName = NULL;
234     }
235 
236   this->Modified();
237 }
238 
239 //----------------------------------------------------------------------------
240 // This function sets the prefix of the file name. "image" would be the
241 // name of a series: image.1, image.2 ...
SetFilePrefix(const char * prefix)242 void vtkImageReader2::SetFilePrefix(const char *prefix)
243 {
244   if ( this->FilePrefix && prefix && (!strcmp(this->FilePrefix,prefix)))
245     {
246     return;
247     }
248   if (!prefix && !this->FilePrefix)
249     {
250     return;
251     }
252   delete [] this->FilePrefix;
253   this->FilePrefix = NULL;
254   if (prefix)
255     {
256     this->FilePrefix = new char[strlen(prefix) + 1];
257     strcpy(this->FilePrefix, prefix);
258 
259     delete [] this->FileName;
260     this->FileName = NULL;
261     if (this->FileNames)
262       {
263       this->FileNames->Delete();
264       this->FileNames = NULL;
265       }
266     }
267 
268   this->Modified();
269 }
270 
271 //----------------------------------------------------------------------------
272 // This function sets the pattern of the file name which turn a prefix
273 // into a file name. "%s.%03d" would be the
274 // pattern of a series: image.001, image.002 ...
SetFilePattern(const char * pattern)275 void vtkImageReader2::SetFilePattern(const char *pattern)
276 {
277   if ( this->FilePattern && pattern &&
278        (!strcmp(this->FilePattern,pattern)))
279     {
280     return;
281     }
282   if (!pattern && !this->FilePattern)
283     {
284     return;
285     }
286   if (this->FilePattern)
287     {
288     delete [] this->FilePattern;
289     this->FilePattern = NULL;
290     }
291   if (pattern)
292     {
293     this->FilePattern = new char[strlen(pattern) + 1];
294     strcpy(this->FilePattern, pattern);
295 
296     if (this->FileName)
297       {
298       delete [] this->FileName;
299       this->FileName = NULL;
300       }
301     if (this->FileNames)
302       {
303       this->FileNames->Delete();
304       this->FileNames = NULL;
305       }
306     }
307 
308   this->Modified();
309 }
310 
311 //----------------------------------------------------------------------------
SetDataByteOrderToBigEndian()312 void vtkImageReader2::SetDataByteOrderToBigEndian()
313 {
314 #ifndef VTK_WORDS_BIGENDIAN
315   this->SwapBytesOn();
316 #else
317   this->SwapBytesOff();
318 #endif
319 }
320 
321 //----------------------------------------------------------------------------
SetDataByteOrderToLittleEndian()322 void vtkImageReader2::SetDataByteOrderToLittleEndian()
323 {
324 #ifdef VTK_WORDS_BIGENDIAN
325   this->SwapBytesOn();
326 #else
327   this->SwapBytesOff();
328 #endif
329 }
330 
331 //----------------------------------------------------------------------------
SetDataByteOrder(int byteOrder)332 void vtkImageReader2::SetDataByteOrder(int byteOrder)
333 {
334   if ( byteOrder == VTK_FILE_BYTE_ORDER_BIG_ENDIAN )
335     {
336     this->SetDataByteOrderToBigEndian();
337     }
338   else
339     {
340     this->SetDataByteOrderToLittleEndian();
341     }
342 }
343 
344 //----------------------------------------------------------------------------
GetDataByteOrder()345 int vtkImageReader2::GetDataByteOrder()
346 {
347 #ifdef VTK_WORDS_BIGENDIAN
348   if ( this->SwapBytes )
349     {
350     return VTK_FILE_BYTE_ORDER_LITTLE_ENDIAN;
351     }
352   else
353     {
354     return VTK_FILE_BYTE_ORDER_BIG_ENDIAN;
355     }
356 #else
357   if ( this->SwapBytes )
358     {
359     return VTK_FILE_BYTE_ORDER_BIG_ENDIAN;
360     }
361   else
362     {
363     return VTK_FILE_BYTE_ORDER_LITTLE_ENDIAN;
364     }
365 #endif
366 }
367 
368 //----------------------------------------------------------------------------
GetDataByteOrderAsString()369 const char *vtkImageReader2::GetDataByteOrderAsString()
370 {
371 #ifdef VTK_WORDS_BIGENDIAN
372   if ( this->SwapBytes )
373     {
374     return "LittleEndian";
375     }
376   else
377     {
378     return "BigEndian";
379     }
380 #else
381   if ( this->SwapBytes )
382     {
383     return "BigEndian";
384     }
385   else
386     {
387     return "LittleEndian";
388     }
389 #endif
390 }
391 
392 
393 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)394 void vtkImageReader2::PrintSelf(ostream& os, vtkIndent indent)
395 {
396   int idx;
397 
398   this->Superclass::PrintSelf(os,indent);
399 
400   // this->File, this->Colors need not be printed
401   os << indent << "FileName: " <<
402     (this->FileName ? this->FileName : "(none)") << "\n";
403   os << indent << "FileNames: " << this->FileNames << "\n";
404   os << indent << "FilePrefix: " <<
405     (this->FilePrefix ? this->FilePrefix : "(none)") << "\n";
406   os << indent << "FilePattern: " <<
407     (this->FilePattern ? this->FilePattern : "(none)") << "\n";
408 
409   os << indent << "FileNameSliceOffset: "
410      << this->FileNameSliceOffset << "\n";
411   os << indent << "FileNameSliceSpacing: "
412      << this->FileNameSliceSpacing << "\n";
413 
414   os << indent << "DataScalarType: "
415      << vtkImageScalarTypeNameMacro(this->DataScalarType) << "\n";
416   os << indent << "NumberOfScalarComponents: "
417      << this->NumberOfScalarComponents << "\n";
418 
419   os << indent << "File Dimensionality: " << this->FileDimensionality << "\n";
420 
421   os << indent << "File Lower Left: " <<
422     (this->FileLowerLeft ? "On\n" : "Off\n");
423 
424   os << indent << "Swap Bytes: " << (this->SwapBytes ? "On\n" : "Off\n");
425 
426   os << indent << "DataIncrements: (" << this->DataIncrements[0];
427   for (idx = 1; idx < 2; ++idx)
428     {
429     os << ", " << this->DataIncrements[idx];
430     }
431   os << ")\n";
432 
433   os << indent << "DataExtent: (" << this->DataExtent[0];
434   for (idx = 1; idx < 6; ++idx)
435     {
436     os << ", " << this->DataExtent[idx];
437     }
438   os << ")\n";
439 
440   os << indent << "DataSpacing: (" << this->DataSpacing[0];
441   for (idx = 1; idx < 3; ++idx)
442     {
443     os << ", " << this->DataSpacing[idx];
444     }
445   os << ")\n";
446 
447   os << indent << "DataOrigin: (" << this->DataOrigin[0];
448   for (idx = 1; idx < 3; ++idx)
449     {
450     os << ", " << this->DataOrigin[idx];
451     }
452   os << ")\n";
453 
454   os << indent << "HeaderSize: " << this->HeaderSize << "\n";
455 
456   if ( this->InternalFileName )
457     {
458     os << indent << "Internal File Name: " << this->InternalFileName << "\n";
459     }
460   else
461     {
462     os << indent << "Internal File Name: (none)\n";
463     }
464 }
465 
466 //----------------------------------------------------------------------------
ExecuteInformation()467 void vtkImageReader2::ExecuteInformation()
468 {
469   // this is empty, the idea is that converted filters should implement
470   // RequestInformation. But to help out old filters we will call
471   // ExecuteInformation and hope that the subclasses correctly set the ivars
472   // and not the output.
473 }
474 
475 //----------------------------------------------------------------------------
476 // This method returns the largest data that can be generated.
RequestInformation(vtkInformation * vtkNotUsed (request),vtkInformationVector ** vtkNotUsed (inputVector),vtkInformationVector * outputVector)477 int vtkImageReader2::RequestInformation (
478   vtkInformation       * vtkNotUsed( request ),
479   vtkInformationVector** vtkNotUsed( inputVector ),
480   vtkInformationVector * outputVector)
481 {
482   this->SetErrorCode( vtkErrorCode::NoError );
483   // call for backwards compatibility
484   this->ExecuteInformation();
485   // Check for any error set by downstream filter (IO in most case)
486   if ( this->GetErrorCode() )
487     {
488     return 0;
489     }
490 
491   // get the info objects
492   vtkInformation* outInfo = outputVector->GetInformationObject(0);
493 
494   // if a list of file names is supplied, set slice extent
495   if (this->FileNames && this->FileNames->GetNumberOfValues() > 0)
496     {
497     this->DataExtent[4] = 0;
498     this->DataExtent[5] = this->FileNames->GetNumberOfValues()-1;
499     }
500 
501   outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
502                this->DataExtent, 6);
503   outInfo->Set(vtkDataObject::SPACING(), this->DataSpacing, 3);
504   outInfo->Set(vtkDataObject::ORIGIN(),  this->DataOrigin, 3);
505 
506   vtkDataObject::SetPointDataActiveScalarInfo(outInfo, this->DataScalarType,
507     this->NumberOfScalarComponents);
508 
509   outInfo->Set(CAN_PRODUCE_SUB_EXTENT(), 1);
510 
511   return 1;
512 }
513 
514 //----------------------------------------------------------------------------
515 // Manual initialization.
SetHeaderSize(unsigned long size)516 void vtkImageReader2::SetHeaderSize(unsigned long size)
517 {
518   if (size != this->HeaderSize)
519     {
520     this->HeaderSize = size;
521     this->Modified();
522     }
523   this->ManualHeaderSize = 1;
524 }
525 
526 
527 //----------------------------------------------------------------------------
528 template <class T>
vtkImageReader2GetSize(T *)529 unsigned long vtkImageReader2GetSize(T*)
530 {
531   return sizeof(T);
532 }
533 
534 //----------------------------------------------------------------------------
535 // This function opens a file to determine the file size, and to
536 // automatically determine the header size.
ComputeDataIncrements()537 void vtkImageReader2::ComputeDataIncrements()
538 {
539   int idx;
540   unsigned long fileDataLength;
541 
542   // Determine the expected length of the data ...
543   switch (this->DataScalarType)
544     {
545     vtkTemplateMacro(
546       fileDataLength = vtkImageReader2GetSize(static_cast<VTK_TT*>(0))
547       );
548     default:
549       vtkErrorMacro(<< "Unknown DataScalarType");
550       return;
551     }
552 
553   fileDataLength *= this->NumberOfScalarComponents;
554 
555   // compute the fileDataLength (in units of bytes)
556   for (idx = 0; idx < 3; ++idx)
557     {
558     this->DataIncrements[idx] = fileDataLength;
559     fileDataLength = fileDataLength *
560       (this->DataExtent[idx*2+1] - this->DataExtent[idx*2] + 1);
561     }
562   this->DataIncrements[3] = fileDataLength;
563 }
564 
565 
566 //----------------------------------------------------------------------------
OpenFile()567 int vtkImageReader2::OpenFile()
568 {
569   if (!this->FileName && !this->FilePattern)
570     {
571     vtkErrorMacro(<<"Either a FileName, FileNames, or FilePattern"
572                   << " must be specified.");
573     return 0;
574     }
575 
576   // Close file from any previous image
577   if (this->File)
578     {
579     this->File->close();
580     delete this->File;
581     this->File = NULL;
582     }
583 
584   // Open the new file
585   vtkDebugMacro(<< "Initialize: opening file " << this->InternalFileName);
586   struct stat fs;
587   if ( !stat( this->InternalFileName, &fs) )
588     {
589 #ifdef _WIN32
590     this->File = new ifstream(this->InternalFileName, ios::in | ios::binary);
591 #else
592     this->File = new ifstream(this->InternalFileName, ios::in);
593 #endif
594     }
595   if (! this->File || this->File->fail())
596     {
597     vtkErrorMacro(<< "Initialize: Could not open file "
598                   << this->InternalFileName);
599     return 0;
600     }
601   return 1;
602 }
603 
604 
605 //----------------------------------------------------------------------------
GetHeaderSize()606 unsigned long vtkImageReader2::GetHeaderSize()
607 {
608   unsigned long firstIdx;
609 
610   if (this->FileNames)
611     {
612     // if FileNames is used, indexing always starts at zero
613     firstIdx = 0;
614     }
615   else
616     {
617     // FilePrefix uses the DataExtent to figure out the first slice index
618     firstIdx = this->DataExtent[4];
619     }
620 
621   return this->GetHeaderSize(firstIdx);
622 }
623 
624 //----------------------------------------------------------------------------
GetHeaderSize(unsigned long idx)625 unsigned long vtkImageReader2::GetHeaderSize(unsigned long idx)
626 {
627   if (!this->FileName && !this->FilePattern)
628     {
629     vtkErrorMacro(<<"Either a FileName or FilePattern must be specified.");
630     return 0;
631     }
632   if ( ! this->ManualHeaderSize)
633     {
634     this->ComputeDataIncrements();
635 
636     // make sure we figure out a filename to open
637     this->ComputeInternalFileName(idx);
638 
639     struct stat statbuf;
640     if (!stat(this->InternalFileName, &statbuf))
641       {
642       return (int)(statbuf.st_size -
643                    (long)this->DataIncrements[this->GetFileDimensionality()]);
644       }
645     }
646 
647   return this->HeaderSize;
648 }
649 
650 //----------------------------------------------------------------------------
SeekFile(int i,int j,int k)651 void vtkImageReader2::SeekFile(int i, int j, int k)
652 {
653   unsigned long streamStart;
654 
655   // convert data extent into constants that can be used to seek.
656   streamStart =
657     (i - this->DataExtent[0]) * this->DataIncrements[0];
658 
659   if (this->FileLowerLeft)
660     {
661     streamStart = streamStart +
662       (j - this->DataExtent[2]) * this->DataIncrements[1];
663     }
664   else
665     {
666     streamStart = streamStart +
667       (this->DataExtent[3] - this->DataExtent[2] - j) *
668       this->DataIncrements[1];
669     }
670 
671   // handle three and four dimensional files
672   if (this->GetFileDimensionality() >= 3)
673     {
674     streamStart = streamStart +
675       (k - this->DataExtent[4]) * this->DataIncrements[2];
676     }
677 
678   streamStart += this->GetHeaderSize(k);
679 
680   // error checking
681   if (!this->File)
682     {
683     vtkWarningMacro(<<"File must be specified.");
684     return;
685     }
686 
687   this->File->seekg((long)streamStart, ios::beg);
688   if (this->File->fail())
689     {
690     vtkWarningMacro("File operation failed.");
691     return;
692     }
693 }
694 
695 //----------------------------------------------------------------------------
696 // This function reads in one data of data.
697 // templated to handle different data types.
698 template <class OT>
vtkImageReader2Update(vtkImageReader2 * self,vtkImageData * data,OT * outPtr)699 void vtkImageReader2Update(vtkImageReader2 *self, vtkImageData *data, OT *outPtr)
700 {
701   vtkIdType outIncr[3];
702   OT *outPtr1, *outPtr2;
703   long streamRead;
704   int idx1, idx2, nComponents;
705   int outExtent[6];
706   unsigned long count = 0;
707   unsigned long target;
708 
709   // Get the requested extents and increments
710   data->GetExtent(outExtent);
711   data->GetIncrements(outIncr);
712   nComponents = data->GetNumberOfScalarComponents();
713 
714   // length of a row, num pixels read at a time
715   int pixelRead = outExtent[1] - outExtent[0] + 1;
716   streamRead = (long)(pixelRead*nComponents*sizeof(OT));
717 
718   // create a buffer to hold a row of the data
719   target = (unsigned long)((outExtent[5]-outExtent[4]+1)*
720                            (outExtent[3]-outExtent[2]+1)/50.0);
721   target++;
722 
723   // read the data row by row
724   if (self->GetFileDimensionality() == 3)
725     {
726     self->ComputeInternalFileName(0);
727     if ( !self->OpenFile() )
728       {
729       return;
730       }
731     }
732   outPtr2 = outPtr;
733   for (idx2 = outExtent[4]; idx2 <= outExtent[5]; ++idx2)
734     {
735     if (self->GetFileDimensionality() == 2)
736       {
737       self->ComputeInternalFileName(idx2);
738       if ( !self->OpenFile() )
739         {
740         return;
741         }
742       }
743     outPtr1 = outPtr2;
744     for (idx1 = outExtent[2];
745          !self->AbortExecute && idx1 <= outExtent[3]; ++idx1)
746       {
747       if (!(count%target))
748         {
749         self->UpdateProgress(count/(50.0*target));
750         }
751       count++;
752 
753       // seek to the correct row
754       self->SeekFile(outExtent[0],idx1,idx2);
755       // read the row.
756       if ( !self->GetFile()->read((char *)outPtr1, streamRead))
757         {
758         vtkGenericWarningMacro("File operation failed. row = " << idx1
759                                << ", Read = " << streamRead
760                                << ", FilePos = " << static_cast<vtkIdType>(self->GetFile()->tellg()));
761         return;
762         }
763       // handle swapping
764       if (self->GetSwapBytes() && sizeof(OT) > 1)
765         {
766         vtkByteSwap::SwapVoidRange(outPtr1, pixelRead*nComponents, sizeof(OT));
767         }
768       outPtr1 += outIncr[1];
769       }
770     // move to the next image in the file and data
771     outPtr2 += outIncr[2];
772     }
773 }
774 
775 //----------------------------------------------------------------------------
776 // This function reads a data from a file.  The datas extent/axes
777 // are assumed to be the same as the file extent/order.
ExecuteDataWithInformation(vtkDataObject * output,vtkInformation * outInfo)778 void vtkImageReader2::ExecuteDataWithInformation(vtkDataObject *output,
779                                                  vtkInformation *outInfo)
780 {
781   vtkImageData *data = this->AllocateOutputData(output, outInfo);
782 
783   void *ptr;
784 
785   if (!this->FileName && !this->FilePattern)
786     {
787     vtkErrorMacro("Either a valid FileName or FilePattern must be specified.");
788     return;
789     }
790 
791   data->GetPointData()->GetScalars()->SetName("ImageFile");
792 
793 #ifndef NDEBUG
794   int *ext = data->GetExtent();
795 #endif
796 
797   vtkDebugMacro("Reading extent: " << ext[0] << ", " << ext[1] << ", "
798         << ext[2] << ", " << ext[3] << ", " << ext[4] << ", " << ext[5]);
799 
800   this->ComputeDataIncrements();
801 
802   // Call the correct templated function for the output
803   ptr = data->GetScalarPointer();
804   switch (this->GetDataScalarType())
805     {
806     vtkTemplateMacro(vtkImageReader2Update(this, data, (VTK_TT *)(ptr)));
807     default:
808       vtkErrorMacro(<< "UpdateFromFile: Unknown data type");
809     }
810 }
811 
812 //----------------------------------------------------------------------------
SetMemoryBuffer(void * membuf)813 void vtkImageReader2::SetMemoryBuffer(void *membuf)
814 {
815   if (this->MemoryBuffer != membuf)
816     {
817     this->MemoryBuffer = membuf;
818     this->Modified();
819     }
820 }
821 
822 //----------------------------------------------------------------------------
SetMemoryBufferLength(vtkIdType buflen)823 void vtkImageReader2::SetMemoryBufferLength(vtkIdType buflen)
824 {
825   if (this->MemoryBufferLength != buflen)
826     {
827     this->MemoryBufferLength = buflen;
828     this->Modified();
829     }
830 }
831 
832 //----------------------------------------------------------------------------
833 // Set the data type of pixels in the file.
834 // If you want the output scalar type to have a different value, set it
835 // after this method is called.
SetDataScalarType(int type)836 void vtkImageReader2::SetDataScalarType(int type)
837 {
838   if (type == this->DataScalarType)
839     {
840     return;
841     }
842 
843   this->Modified();
844   this->DataScalarType = type;
845   // Set the default output scalar type
846   vtkImageData::SetScalarType(this->DataScalarType,
847                               this->GetOutputInformation(0));
848 }
849