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