Orfeo Toolbox  3.16
itkImageIOBase.cxx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkImageIOBase.cxx,v $
5  Language: C++
6  Date: $Date: 2010-06-14 18:55:23 $
7  Version: $Revision: 1.90 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 #if defined(_MSC_VER)
18 #pragma warning ( disable : 4786 )
19 #endif
20 #include "itkImageIOBase.h"
21 #include "itkRGBPixel.h"
22 #include "itkRGBAPixel.h"
23 #include "itkOffset.h"
24 #include "itkVector.h"
25 #include "itkPoint.h"
26 #include "itkCovariantVector.h"
28 #include "itkDiffusionTensor3D.h"
29 #include "itkFixedArray.h"
30 #include "itkImageRegionSplitter.h"
31 
32 namespace itk
33 {
34 
36  m_PixelType(SCALAR),
37  m_ComponentType(UNKNOWNCOMPONENTTYPE),
38  m_ByteOrder(OrderNotApplicable),
39  m_FileType(TypeNotApplicable),
40  m_NumberOfDimensions(0)
41 {
42  Reset(false);
43 }
44 
45 
46 void ImageIOBase::Reset(const bool)
47 {
48  m_Initialized = false;
49  m_FileName = "";
51  for (unsigned int i=0; i < m_NumberOfDimensions; i++)
52  {
53  m_Dimensions[i] = 0;
54  m_Strides[i] = 0;
55  }
56  m_NumberOfDimensions = 0;
57  m_UseCompression = false;
58  m_UseStreamedReading = false;
59  m_UseStreamedWriting = false;
60 }
61 
63 {
64 }
65 
68 {
69  return this->m_SupportedWriteExtensions;
70 }
71 
74 {
75  return this->m_SupportedReadExtensions;
76 }
77 
78 void ImageIOBase::AddSupportedReadExtension( const char * extension )
79 {
80  this->m_SupportedReadExtensions.push_back( extension );
81 }
82 
83 void ImageIOBase::AddSupportedWriteExtension( const char * extension )
84 {
85  this->m_SupportedWriteExtensions.push_back( extension );
86 }
87 
88 void ImageIOBase::Resize(const unsigned int numDimensions,
89  const unsigned int* dimensions)
90 {
91  m_NumberOfDimensions = numDimensions;
92  if (dimensions != NULL)
93  {
94  for (unsigned int i=0; i < m_NumberOfDimensions; i++)
95  {
96  m_Dimensions[i] = dimensions[i];
97  }
99  }
100 }
101 
102 void ImageIOBase::SetDimensions(unsigned int i, unsigned int dim)
103 {
104  if ( i >= m_Dimensions.size() )
105  {
106  itkWarningMacro("Index: " << i <<
107  " is out of bounds, expected maximum is " <<
108  m_Dimensions.size());
109  itkExceptionMacro("Index: " << i <<
110  " is out of bounds, expected maximum is " <<
111  m_Dimensions.size());
112  }
113  this->Modified();
114  m_Dimensions[i] = dim;
115 }
116 
117 void ImageIOBase::SetOrigin(unsigned int i, double origin)
118 {
119  if ( i >= m_Origin.size() )
120  {
121  itkWarningMacro("Index: " << i <<
122  " is out of bounds, expected maximum is " <<
123  m_Origin.size());
124  itkExceptionMacro("Index: " << i <<
125  " is out of bounds, expected maximum is " <<
126  m_Origin.size());
127  }
128  this->Modified();
129  m_Origin[i] = origin;
130 }
131 
132 void ImageIOBase::SetSpacing(unsigned int i, double spacing)
133 {
134  if (i >= m_Spacing.size() )
135  {
136  itkWarningMacro("Index: " << i <<
137  " is out of bounds, expected maximum is " <<
138  m_Spacing.size());
139  itkExceptionMacro("Index: " << i <<
140  " is out of bounds, expected maximum is " <<
141  m_Spacing.size());
142  }
143  this->Modified();
144  m_Spacing[i] = spacing;
145 }
146 
147 void ImageIOBase::SetDirection(unsigned int i, std::vector<double> &direction)
148 {
149  if (i >= m_Direction.size() )
150  {
151  itkWarningMacro("Index: " << i <<
152  " is out of bounds, expected maximum is " <<
153  m_Direction.size());
154  itkExceptionMacro("Index: " << i <<
155  " is out of bounds, expected maximum is " <<
156  m_Direction.size());
157  }
158  this->Modified();
159  m_Direction[i] = direction;
160 }
161 
162 void ImageIOBase::SetDirection(unsigned int i, vnl_vector<double> &direction)
163 {
164  if (i >= m_Direction.size() )
165  {
166  itkWarningMacro("Index: " << i <<
167  " is out of bounds, expected maximum is " <<
168  m_Direction.size());
169  itkExceptionMacro("Index: " << i <<
170  " is out of bounds, expected maximum is " <<
171  m_Direction.size());
172  }
173  this->Modified();
174  std::vector<double> v;
175  v.resize(m_Direction.size());
176  for (unsigned int j=0; j < v.size(); j++)
177  {
178  v[j] = direction[j];
179  }
180  m_Direction[i] = v;
181 }
182 
183 const std::type_info& ImageIOBase::GetComponentTypeInfo() const
184 {
185  switch(m_ComponentType)
186  {
187  case UCHAR:
188  return typeid(unsigned char);
189  case CHAR:
190  return typeid(char);
191  case USHORT:
192  return typeid(unsigned short);
193  case SHORT:
194  return typeid(short);
195  case UINT:
196  return typeid(unsigned int);
197  case INT:
198  return typeid(int);
199  case ULONG:
200  return typeid(unsigned long);
201  case LONG:
202  return typeid(long);
203  case FLOAT:
204  return typeid(float);
205  case DOUBLE:
206  return typeid(double);
207  case CSHORT:
208  return typeid(std::complex<short>);
209  case CINT:
210  return typeid(std::complex<int>);
211  case CFLOAT:
212  return typeid(std::complex<float>);
213  case CDOUBLE:
214  return typeid(std::complex<double>);
216  default:
217  itkExceptionMacro ("Unknown component type: " << m_ComponentType);
218  }
219  return typeid(ImageIOBase::UnknownType);
220 }
221 
222 //
223 // This macro enforces pixel type information to be available for all different
224 // pixel types.
225 //
226 template <typename T>
227 bool
229  const std::type_info &ptype,
231  T itkNotUsed( dummy ) )
232 {
233  if( ptype == typeid(T) )
234  {
235  This->SetNumberOfComponents(1);
236  This->SetComponentType(ntype);
238  return true;
239  }
240  else if ( ptype == typeid(RGBPixel<T>) )
241  {
242  This->SetNumberOfComponents(3);
243  This->SetComponentType(ntype);
245  return true;
246  }
247  else if ( ptype == typeid(RGBAPixel<T>) )
248  {
249  This->SetNumberOfComponents(4);
250  This->SetComponentType(ntype);
252  return true;
253  }
254  else if ( ptype == typeid(Vector<T,2>) )
255  {
256  This->SetNumberOfComponents(2);
258  This->SetComponentType(ntype);
259  return true;
260  }
261  else if ( ptype == typeid(Vector<T,3>) )
262  {
263  This->SetNumberOfComponents(3);
265  This->SetComponentType(ntype);
266  return true;
267  }
268  else if ( ptype == typeid(Vector<T,4>) )
269  {
270  This->SetNumberOfComponents(4);
272  This->SetComponentType(ntype);
273  return true;
274  }
275  else if ( ptype == typeid(Vector<T,5>) )
276  {
277  This->SetNumberOfComponents(5);
279  This->SetComponentType(ntype);
280  return true;
281  }
282  else if ( ptype == typeid(Vector<T,6>) )
283  {
284  This->SetNumberOfComponents(6);
286  This->SetComponentType(ntype);
287  return true;
288  }
289  else if ( ptype == typeid(Vector<T,7>) )
290  {
291  This->SetNumberOfComponents(7);
293  This->SetComponentType(ntype);
294  return true;
295  }
296  else if ( ptype == typeid(CovariantVector<T,2>) )
297  {
298  This->SetNumberOfComponents(2);
300  This->SetComponentType(ntype);
301  return true;
302  }
303  else if ( ptype == typeid(CovariantVector<T,3>) )
304  {
305  This->SetNumberOfComponents(3);
307  This->SetComponentType(ntype);
308  return true;
309  }
310  else if ( ptype == typeid(CovariantVector<T,4>) )
311  {
312  This->SetNumberOfComponents(4);
314  This->SetComponentType(ntype);
315  return true;
316  }
317  else if ( ptype == typeid(CovariantVector<T,5>) )
318  {
319  This->SetNumberOfComponents(5);
321  This->SetComponentType(ntype);
322  return true;
323  }
324  else if ( ptype == typeid(CovariantVector<T,6>) )
325  {
326  This->SetNumberOfComponents(6);
328  This->SetComponentType(ntype);
329  return true;
330  }
331  else if ( ptype == typeid(CovariantVector<T,7>) )
332  {
333  This->SetNumberOfComponents(7);
335  This->SetComponentType(ntype);
336  return true;
337  }
338  else if ( ptype == typeid(FixedArray<T,2>) )
339  {
340  This->SetNumberOfComponents(2);
342  This->SetComponentType(ntype);
343  return true;
344  }
345  else if ( ptype == typeid(FixedArray<T,3>) )
346  {
347  This->SetNumberOfComponents(3);
349  This->SetComponentType(ntype);
350  return true;
351  }
352  else if ( ptype == typeid(FixedArray<T,4>) )
353  {
354  This->SetNumberOfComponents(4);
356  This->SetComponentType(ntype);
357  return true;
358  }
359  else if ( ptype == typeid(SymmetricSecondRankTensor<T,2>) )
360  {
361  This->SetNumberOfComponents(3);
363  This->SetComponentType(ntype);
364  return true;
365  }
366  else if ( ptype == typeid(SymmetricSecondRankTensor<T,3>) )
367  {
368  This->SetNumberOfComponents(6);
370  This->SetComponentType(ntype);
371  return true;
372  }
373  else if ( ptype == typeid(SymmetricSecondRankTensor<T,4>) )
374  {
375  This->SetNumberOfComponents(10);
377  This->SetComponentType(ntype);
378  return true;
379  }
380  else if ( ptype == typeid(SymmetricSecondRankTensor<T,5>) )
381  {
382  This->SetNumberOfComponents(15);
384  This->SetComponentType(ntype);
385  return true;
386  }
387  else if ( ptype == typeid(SymmetricSecondRankTensor<T,6>) )
388  {
389  This->SetNumberOfComponents(21);
391  This->SetComponentType(ntype);
392  return true;
393  }
394  else if ( ptype == typeid(DiffusionTensor3D<T>) )
395  {
396  This->SetNumberOfComponents(6);
397  This->SetComponentType(ntype);
399  return true;
400  }
401  else if ( ptype == typeid(Matrix<T,2,2>) )
402  {
403  This->SetNumberOfComponents(4);
404  This->SetComponentType(ntype);
406  return true;
407  }
408  else if ( ptype == typeid(Matrix<T,3,3>) )
409  {
410  This->SetNumberOfComponents(9);
411  This->SetComponentType(ntype);
413  return true;
414  }
415  else if ( ptype == typeid(Matrix<T,4,4>) )
416  {
417  This->SetNumberOfComponents(16);
418  This->SetComponentType(ntype);
420  return true;
421  }
422  return false;
423 }
424 
425 //
426 // This macro enforces pixel type information to be available for all different
427 // pixel types.
428 //
429 template <typename T>
430 bool
432  const std::type_info &ptype,
434  std::complex<T> itkNotUsed( dummy ) )
435 {
436  /*std::cout << "itkSetPixelType() specialized way" << std::endl;
437  std::cout << "ptype.name() = " << ptype.name() <<std::endl;
438  std::cout << "ntype = " << ntype <<std::endl;*/
439 
440  if (ptype == typeid(std::complex<short>))
441  {
442  std::cout << "complex short detected" << std::endl;
443  This->SetNumberOfComponents(1);
446  return true;
447  }
448  if (ptype == typeid(std::complex<int>))
449  {
450  //std::cout << "complex int detected" <<std::endl;
451  This->SetNumberOfComponents(1);
454  return true;
455  }
456  if (ptype == typeid(std::complex<float>))
457  {
458  //std::cout << "complex float detected" <<std::endl;
459  This->SetNumberOfComponents(1);
462  return true;
463  }
464  if (ptype == typeid(std::complex<double>))
465  {
466  //std::cout << "complex double detected" <<std::endl;
467  This->SetNumberOfComponents(1);
470  return true;
471  }
472  return false;
473 }
474 
475 
476 bool ImageIOBase::SetPixelTypeInfo(const std::type_info& ptype)
477 {
478  //std::cout << " SetPixelTypeInfo -> BEGIN ..." <<std::endl;
479  this->SetNumberOfComponents(1);
482 
483 
484  if (!itkSetPixelType(this,ptype,ImageIOBase::CHAR, char(0) ) &&
485  !itkSetPixelType(this,ptype,ImageIOBase::UCHAR, (unsigned char)0) &&
486  !itkSetPixelType(this,ptype,ImageIOBase::SHORT,(short)(0)) &&
487  !itkSetPixelType(this,ptype,ImageIOBase::USHORT,(unsigned short)(0)) &&
488  !itkSetPixelType(this,ptype,ImageIOBase::INT,(int)(0)) &&
489  !itkSetPixelType(this,ptype,ImageIOBase::UINT,(unsigned int)(0)) &&
490  !itkSetPixelType(this,ptype,ImageIOBase::LONG,(long)(0)) &&
491  !itkSetPixelType(this,ptype,ImageIOBase::ULONG,(unsigned long)(0)) &&
492  !itkSetPixelType(this,ptype,ImageIOBase::FLOAT,(float)(0)) &&
493  !itkSetPixelType(this,ptype,ImageIOBase::DOUBLE,(double)(0)) &&
494  !itkSetPixelType(this,ptype,ImageIOBase::CSHORT,(std::complex<short>)(0)) &&
495  !itkSetPixelType(this,ptype,ImageIOBase::CINT,(std::complex<int>)(0)) &&
496  !itkSetPixelType(this,ptype,ImageIOBase::CFLOAT,(std::complex<float>)(0)) &&
497  !itkSetPixelType(this,ptype,ImageIOBase::CDOUBLE,(std::complex<double>)(0)) )
498  {
499  if ( ptype == typeid(Offset<2>) )
500  {
501  this->SetNumberOfComponents(2);
504  }
505  else if ( ptype == typeid(Offset<3>) )
506  {
507  this->SetNumberOfComponents(3);
510  }
511  else if ( ptype == typeid(Offset<4>) )
512  {
513  this->SetNumberOfComponents(4);
516  }
517 
518  }
519 
521  {
522  itkExceptionMacro("Pixel type currently not supported. typeid.name = " << ptype.name() );
523  return false;
524  }
525 
527  {
528  itkExceptionMacro("Pixel Component type currently not supported. typeid.name = " << ptype.name() );
529  return false;
530  }
531 
532  /*std::cout << "ComponentType: " << this->GetComponentTypeInfo().name() <<std::endl;
533  std::cout << "ComponentSize: " <<this->GetComponentSize() <<std::endl;
534  std::cout << "Nb of Component: " <<this->GetNumberOfComponents() <<std::endl;
535  std::cout << "Pixel Type: " <<this->GetPixelTypeAsString(this->GetPixelType()) <<std::endl;
536  std::cout << " SetPixelTypeInfo -> ... END" <<std::endl;*/
537  return true;
538 }
539 
541 {
542  unsigned int i;
543 
544  m_Strides[0] = this->GetComponentSize();
546  for (i = 2; i <= (m_NumberOfDimensions+1); i++)
547  {
548  m_Strides[i] = m_Dimensions[i-2] * m_Strides[i-1];
549  }
550 }
551 
552 // Calculates the image size in PIXELS
556 {
557  unsigned int i;
558  SizeType numPixels = 1;
559 
560  for (i = 0; i < m_NumberOfDimensions; i++)
561  {
562  numPixels *= m_Dimensions[i];
563  }
564 
565  return numPixels;
566 }
567 
571 {
572  return (this->GetImageSizeInPixels() * m_NumberOfComponents);
573 }
574 
578 {
579  return (this->GetImageSizeInComponents() * this->GetComponentSize());
580 }
581 
585 {
586  return m_Strides[0];
587 }
588 
592 {
593  return m_Strides[1];
594 }
595 
599 {
600  return m_Strides[2];
601 }
602 
606 {
607  return m_Strides[3];
608 }
609 
611 {
612  if(dim != m_NumberOfDimensions)
613  {
614  m_Origin.resize( dim );
615  m_Spacing.resize( dim );
616  m_Direction.resize( dim );
617  m_Strides.resize( dim+2 );
618  m_NumberOfDimensions = dim;
619  m_Dimensions.resize( dim );
620  m_Direction.resize( dim );
621  std::vector<double> axis( dim );
622  for (unsigned int i=0; i<dim; i++)
623  {
624  for (unsigned int j=0; j < dim; j++)
625  {
626  if (i == j)
627  {
628  axis[j] = 1.0;
629  }
630  else
631  {
632  axis[j] = 0.0;
633  }
634  }
635  this->SetDirection(i, axis);
636  this->SetOrigin(i, 0.0);
637  this->SetSpacing(i, 1.0);
638  }
639  this->Modified();
640  }
641 }
642 
643 bool
645 ::ReadBufferAsBinary(std::istream& is, void *buffer, ImageIOBase::SizeType num)
646 {
647 
648  const std::streamsize numberOfBytesToBeRead = Math::CastWithRangeCheck< std::streamsize>( num );
649 
650  is.read( static_cast<char *>( buffer ), numberOfBytesToBeRead );
651 
652  const std::streamsize numberOfBytesRead = is.gcount();
653 
654 #ifdef __APPLE_CC__
655  // fail() is broken in the Mac. It returns true when reaches eof().
656  if ( numberOfBytesRead != numberOfBytesToBeRead )
657 #else
658  if ( ( numberOfBytesRead != numberOfBytesToBeRead ) || is.fail() )
659 #endif
660  {
661  return false; // read failed
662  }
663 
664  return true;
665 
666 }
667 
668 
669 unsigned int ImageIOBase::GetPixelSize() const
670 {
673  {
674  itkExceptionMacro ("Unknown pixel or component type: ("
675  << m_PixelType << ", " << m_ComponentType << ")");
676  return 0;
677  }
678 
679  return this->GetComponentSize() * this->GetNumberOfComponents();
680 }
681 
682 
683 unsigned int ImageIOBase::GetComponentSize() const
684 {
685  switch(m_ComponentType)
686  {
687  case UCHAR:
688  return sizeof(unsigned char);
689  case CHAR:
690  return sizeof(char);
691  case USHORT:
692  return sizeof(unsigned short);
693  case SHORT:
694  return sizeof(short);
695  case UINT:
696  return sizeof(unsigned int);
697  case INT:
698  return sizeof(int);
699  case ULONG:
700  return sizeof(unsigned long);
701  case LONG:
702  return sizeof(long);
703  case FLOAT:
704  return sizeof(float);
705  case DOUBLE:
706  return sizeof(double);
707  case CSHORT:
708  return sizeof(std::complex<short>);
709  case CINT:
710  return sizeof(std::complex<int>);
711  case CFLOAT:
712  return sizeof(std::complex<float>);
713  case CDOUBLE:
714  return sizeof(std::complex<double>);
716  default:
717  itkExceptionMacro ("Unknown component type: " << m_ComponentType);
718  }
719 
720  return 0;
721 }
722 
724 {
725  std::string s;
726  switch(t)
727  {
728  case ASCII:
729  return s = "ASCII";
730  case Binary:
731  return s = "Binary";
732  case TypeNotApplicable:
733  default:
734  return s = "TypeNotApplicable";
735  }
736  return s="TypeNotApplicable";
737 }
738 
740 {
741  std::string s;
742  switch(t)
743  {
744  case BigEndian:
745  return s = "BigEndian";
746  case LittleEndian:
747  return s = "LittleEndian";
748  case OrderNotApplicable:
749  default:
750  return s = "OrderNotApplicable";
751  }
752  return s="OrderNotApplicable";
753 }
754 
756 {
757  std::string s;
758  switch(t)
759  {
760  case UCHAR:
761  return (s = "unsigned_char");
762  case CHAR:
763  return (s = "char");
764  case USHORT:
765  return (s = "unsigned_short");
766  case SHORT:
767  return (s = "short");
768  case UINT:
769  return (s = "unsigned_int");
770  case INT:
771  return (s = "int");
772  case ULONG:
773  return (s = "unsigned_long");
774  case LONG:
775  return (s = "long");
776  case FLOAT:
777  return (s = "float");
778  case DOUBLE:
779  return (s = "double");
780  case CSHORT:
781  return (s = "complex_short");
782  case CINT:
783  return (s = "complex_int");
784  case CFLOAT:
785  return (s = "complex_float");
786  case CDOUBLE:
787  return (s = "complex_double");
789  default:
790  return (s = "unknown");
791  }
792  return (s="unknown");
793 
794 }
795 
797 {
798  std::string s;
799  switch(t)
800  {
801  case SCALAR:
802  return (s = "scalar");
803  case VECTOR:
804  return (s = "vector");
805  case COVARIANTVECTOR:
806  return (s = "covariant_vector");
807  case POINT:
808  return (s = "point");
809  case OFFSET:
810  return (s = "offset");
811  case RGB:
812  return (s = "rgb");
813  case RGBA:
814  return (s = "rgba");
816  return (s = "symmetric_second_rank_tensor");
817  case DIFFUSIONTENSOR3D:
818  return (s = "diffusion_tensor_3D");
819  case COMPLEX:
820  return (s = "complex");
821  case UNKNOWNPIXELTYPE:
822  default:
823  itkExceptionMacro ("Unknown pixel type: " << t);
824  }
825  return (s="unknown");
826 
827 }
828 
829 namespace {
830 template <class TComponent>
831 void WriteBuffer(std::ostream& os, const TComponent *buffer, ImageIOBase::SizeType num)
832 {
833  const TComponent *ptr = buffer;
834  typedef typename itk::NumericTraits<TComponent>::PrintType PrintType;
835  for (ImageIOBase::SizeType i=0; i < num; i++)
836  {
837  if ( !(i%6) && i )
838  os << "\n";
839  os << PrintType(*ptr++) << " ";
840  }
841 }
842 }
843 void ImageIOBase::WriteBufferAsASCII(std::ostream& os, const void *buffer,
844  IOComponentType ctype,
845  ImageIOBase::SizeType numComp)
846 {
847  switch (ctype)
848  {
849  case UCHAR:
850  {
851  typedef const unsigned char * Type;
852  Type buf = reinterpret_cast<Type>(buffer);
853  WriteBuffer(os, buf, numComp);
854  }
855  break;
856  case CHAR:
857  {
858  typedef const char * Type;
859  Type buf = reinterpret_cast<Type>(buffer);
860  WriteBuffer(os, buf, numComp);
861  }
862  break;
863 
864  case USHORT:
865  {
866  typedef const unsigned short * Type;
867  Type buf = reinterpret_cast<Type>(buffer);
868  WriteBuffer(os, buf, numComp);
869  }
870  break;
871 
872  case SHORT:
873  {
874  typedef const short * Type;
875  Type buf = reinterpret_cast<Type>(buffer);
876  WriteBuffer(os, buf, numComp);
877  }
878  break;
879 
880  case UINT:
881  {
882  typedef const unsigned int * Type;
883  Type buf = reinterpret_cast<Type>(buffer);
884  WriteBuffer(os, buf, numComp);
885  }
886  break;
887 
888  case INT:
889  {
890  typedef const int * Type;
891  Type buf = reinterpret_cast<Type>(buffer);
892  WriteBuffer(os, buf, numComp);
893  }
894  break;
895 
896  case ULONG:
897  {
898  typedef const unsigned long * Type;
899  Type buf = reinterpret_cast<Type>(buffer);
900  WriteBuffer(os, buf, numComp);
901  }
902  break;
903 
904  case LONG:
905  {
906  typedef const long * Type;
907  Type buf = reinterpret_cast<Type>(buffer);
908  WriteBuffer(os, buf, numComp);
909  }
910  break;
911 
912  case FLOAT:
913  {
914  typedef const float * Type;
915  Type buf = reinterpret_cast<Type>(buffer);
916  WriteBuffer(os, buf, numComp);
917  }
918  break;
919 
920  case DOUBLE:
921  {
922  typedef const double * Type;
923  Type buf = reinterpret_cast<Type>(buffer);
924  WriteBuffer(os, buf, numComp);
925  }
926  break;
927 
928  case CSHORT:
929  {
930  typedef const std::complex<short> * Type;
931  Type buf = reinterpret_cast<Type>(buffer);
932  WriteBuffer(os, buf, numComp);
933  }
934  break;
935 
936  case CINT:
937  {
938  typedef const std::complex<int> * Type;
939  Type buf = reinterpret_cast<Type>(buffer);
940  WriteBuffer(os, buf, numComp);
941  }
942  break;
943 
944  case CFLOAT:
945  {
946  typedef const std::complex<float> * Type;
947  Type buf = reinterpret_cast<Type>(buffer);
948  WriteBuffer(os, buf, numComp);
949  }
950  break;
951 
952  case CDOUBLE:
953  {
954  typedef const std::complex<double> * Type;
955  Type buf = reinterpret_cast<Type>(buffer);
956  WriteBuffer(os, buf, numComp);
957  }
958  break;
959 
960  default:
961  break;
962  }
963 
964 }
965 
966 
967 template <class TComponent>
968 void ReadBuffer(std::istream& is, TComponent *buffer, ImageIOBase::SizeType num)
969 {
970 
971  typedef typename itk::NumericTraits<TComponent>::PrintType PrintType;
972  PrintType temp;
973  TComponent *ptr = buffer;
974  for( ImageIOBase::SizeType i=0; i < num; i++, ptr++ )
975  {
976  is >> temp;
977  *ptr = static_cast<TComponent>( temp );
978  }
979 }
980 
981 void ImageIOBase::ReadBufferAsASCII(std::istream& is, void *buffer,
982  IOComponentType ctype,
983  ImageIOBase::SizeType numComp)
984 {
985  switch (ctype)
986  {
987  case UCHAR:
988  {
989  unsigned char *buf = reinterpret_cast<unsigned char*>(buffer);
990  ReadBuffer(is, buf, numComp);
991  }
992  break;
993  case CHAR:
994  {
995  char *buf = reinterpret_cast<char*>(buffer);
996  ReadBuffer(is, buf, numComp);
997  }
998  break;
999 
1000  case USHORT:
1001  {
1002  unsigned short *buf = reinterpret_cast<unsigned short*>(buffer);
1003  ReadBuffer(is, buf, numComp);
1004  }
1005  break;
1006 
1007  case SHORT:
1008  {
1009  short *buf = reinterpret_cast<short*>(buffer);
1010  ReadBuffer(is, buf, numComp);
1011  }
1012  break;
1013 
1014  case UINT:
1015  {
1016  unsigned int *buf = reinterpret_cast<unsigned int*>(buffer);
1017  ReadBuffer(is, buf, numComp);
1018  }
1019  break;
1020 
1021  case INT:
1022  {
1023  int *buf = reinterpret_cast<int*>(buffer);
1024  ReadBuffer(is, buf, numComp);
1025  }
1026  break;
1027 
1028  case ULONG:
1029  {
1030  unsigned long *buf = reinterpret_cast<unsigned long*>(buffer);
1031  ReadBuffer(is, buf, numComp);
1032  }
1033  break;
1034 
1035  case LONG:
1036  {
1037  long *buf = reinterpret_cast<long*>(buffer);
1038  ReadBuffer(is, buf, numComp);
1039  }
1040  break;
1041 
1042  case FLOAT:
1043  {
1044  float *buf = reinterpret_cast<float*>(buffer);
1045  ReadBuffer(is, buf, numComp);
1046  }
1047  break;
1048 
1049  case DOUBLE:
1050  {
1051  double *buf = reinterpret_cast<double*>(buffer);
1052  ReadBuffer(is, buf, numComp);
1053  }
1054  break;
1055 
1056  case CSHORT:
1057  {
1058  std::complex<short> *buf = reinterpret_cast<std::complex<short>*>(buffer);
1059  ReadBuffer(is, buf, numComp);
1060  }
1061  break;
1062 
1063  case CINT:
1064  {
1065  std::complex<int> *buf = reinterpret_cast<std::complex<int>*>(buffer);
1066  ReadBuffer(is, buf, numComp);
1067  }
1068  break;
1069 
1070  case CFLOAT:
1071  {
1072  std::complex<float> *buf = reinterpret_cast<std::complex<float>*>(buffer);
1073  ReadBuffer(is, buf, numComp);
1074  }
1075  break;
1076 
1077  case CDOUBLE:
1078  {
1079  std::complex<double> *buf = reinterpret_cast<std::complex<double>*>(buffer);
1080  ReadBuffer(is, buf, numComp);
1081  }
1082  break;
1083 
1084 
1085  default:
1086  break;
1087  }
1088 
1089 }
1090 
1091 
1092 unsigned int
1094  const ImageIORegion &pasteRegion) const
1095 {
1096  // Code from ImageRegionSplitter:GetNumberOfSplits
1097  int splitAxis;
1098  const ImageIORegion::SizeType &regionSize = pasteRegion.GetSize();
1099 
1100 
1101  // split on the outermost dimension available
1102  splitAxis = pasteRegion.GetImageDimension() - 1;
1103  while (regionSize[splitAxis] == 1)
1104  {
1105  --splitAxis;
1106  if (splitAxis < 0)
1107  { // cannot split
1108  itkDebugMacro(" Cannot Split");
1109  return 1;
1110  }
1111  }
1112 
1113  // determine the actual number of pieces that will be generated
1114  ImageIORegion::SizeType::value_type range = regionSize[splitAxis];
1115  int valuesPerPiece = Math::Ceil<int>(range/double(numberOfRequestedSplits));
1116  int maxPieceUsed = Math::Ceil<int>(range/double(valuesPerPiece)) - 1;
1117 
1118  return maxPieceUsed+1;
1119 }
1120 
1121 unsigned int
1122 ImageIOBase::GetActualNumberOfSplitsForWriting(unsigned int numberOfRequestedSplits,
1123  const ImageIORegion &pasteRegion,
1124  const ImageIORegion &largestPossibleRegion)
1125 {
1126  if (this->CanStreamWrite())
1127  {
1128  return GetActualNumberOfSplitsForWritingCanStreamWrite(numberOfRequestedSplits, pasteRegion);
1129  }
1130  if (pasteRegion != largestPossibleRegion)
1131  {
1132  itkExceptionMacro("Pasting is not supported! Can't write:" << this->GetFileName());
1133  }
1134  if (numberOfRequestedSplits != 1)
1135  {
1136  itkDebugMacro("Requested more then 1 splits for streaming");
1137  itkDebugMacro("This IO class does not support streaming!");
1138  }
1139  return 1;
1140 }
1141 
1144  unsigned int numberOfActualSplits,
1145  const ImageIORegion &pasteRegion) const
1146 {
1147  // Code from ImageRegionSplitter:GetSplit
1148  int splitAxis;
1149  ImageIORegion splitRegion;
1150  ImageIORegion::IndexType splitIndex;
1151  ImageIORegion::SizeType splitSize, regionSize;
1152 
1153  // Initialize the splitRegion to the requested region
1154  splitRegion = pasteRegion;
1155  splitIndex = splitRegion.GetIndex();
1156  splitSize = splitRegion.GetSize();
1157 
1158  regionSize = pasteRegion.GetSize();
1159 
1160  // split on the outermost dimension available
1161  splitAxis = pasteRegion.GetImageDimension() - 1;
1162  while (regionSize[splitAxis] == 1)
1163  {
1164  --splitAxis;
1165  if (splitAxis < 0)
1166  { // cannot split
1167  itkDebugMacro(" Cannot Split");
1168  return splitRegion;
1169  }
1170  }
1171 
1172  // determine the actual number of pieces that will be generated
1173  ImageIORegion::SizeType::value_type range = regionSize[splitAxis];
1174  int valuesPerPiece = Math::Ceil<int>(range/(double)numberOfActualSplits);
1175  int maxPieceUsed = Math::Ceil<int>(range/(double)valuesPerPiece) - 1;
1176 
1177  // Split the region
1178  if ((int) ithPiece < maxPieceUsed)
1179  {
1180  splitIndex[splitAxis] += ithPiece*valuesPerPiece;
1181  splitSize[splitAxis] = valuesPerPiece;
1182  }
1183  if ((int) ithPiece == maxPieceUsed)
1184  {
1185  splitIndex[splitAxis] += ithPiece*valuesPerPiece;
1186  // last piece needs to process the "rest" dimension being split
1187  splitSize[splitAxis] = splitSize[splitAxis] - ithPiece*valuesPerPiece;
1188  }
1189 
1190  // set the split region ivars
1191  splitRegion.SetIndex( splitIndex );
1192  splitRegion.SetSize( splitSize );
1193 
1194  itkDebugMacro(" Split Piece: " << splitRegion );
1195 
1196  return splitRegion;
1197 }
1198 
1201  unsigned int numberOfActualSplits,
1202  const ImageIORegion &pasteRegion,
1203  const ImageIORegion &largestPossibleRegion)
1204 {
1205  if (this->CanStreamWrite())
1206  {
1207  return GetSplitRegionForWritingCanStreamWrite(ithPiece, numberOfActualSplits, pasteRegion);
1208  }
1209  return largestPossibleRegion;
1210 }
1211 
1219  const ImageIORegion & requested ) const
1220 {
1221  //
1222  // The default implementations determines that the streamable region is
1223  // equal to the minimal size of the image in the file. That is two
1224  // say the return ImageIORegion::GetImageSizeInPixels() is equal to
1225  // the number in the file.
1226  //
1227 
1228  // Since the image in the file may have a lower or higher dimension
1229  // than the image type over which the ImageFileReader is
1230  // being instantiated we must choose an image dimension which will
1231  // represent all the pixels. That is we can trim trailing 1s.
1232 
1233  unsigned int minIODimension = this->m_NumberOfDimensions;
1234  while (minIODimension)
1235  {
1236  if (this->m_Dimensions[minIODimension-1] == 1)
1237  {
1238  --minIODimension;
1239  }
1240  else
1241  {
1242  break;
1243  }
1244  }
1245 
1246  // dimension size we use to represent the region
1247  unsigned int maxDimension =
1248  minIODimension > requested.GetImageDimension() ? minIODimension : requested.GetImageDimension();
1249 
1250  // First: allocate with the correct dimensions
1251  ImageIORegion streamableRegion( maxDimension );
1252 
1253  // Second: copy only the number of dimension that the file has.
1254  for( unsigned int i=0; i < minIODimension; i++ )
1255  {
1256  streamableRegion.SetSize( i, this->m_Dimensions[i] );
1257  streamableRegion.SetIndex( i, 0 );
1258  }
1259 
1260  // Third: set the rest to the default : start = 0, size = 1
1261  for( unsigned int j=minIODimension; j<streamableRegion.GetImageDimension(); j++ )
1262  {
1263  streamableRegion.SetSize( j, 1 );
1264  streamableRegion.SetIndex( j, 0 );
1265  }
1266 
1267  // Finally: return the streamable region
1268  return streamableRegion;
1269 }
1270 
1274 std::vector<double>
1276 ::GetDefaultDirection( unsigned int k ) const
1277 {
1278  std::vector<double> axis;
1279  axis.resize( this->GetNumberOfDimensions() );
1280 
1281  // Fill up with the equivalent of a line from an Identity matrix
1282  for( unsigned int r=0; r<axis.size(); r++ )
1283  {
1284  axis[r] = 0.0;
1285  }
1286 
1287  axis[k] = 1.0;
1288 
1289  return axis;
1290 }
1291 
1292 void ImageIOBase::PrintSelf(std::ostream& os, Indent indent) const
1293 {
1294  Superclass::PrintSelf(os, indent);
1295 
1296  os << indent << "FileName: " << m_FileName << std::endl;
1297  os << indent << "FileType: " << this->GetFileTypeAsString(m_FileType) << std::endl;
1298  os << indent << "ByteOrder: " << this->GetByteOrderAsString(m_ByteOrder) << std::endl;
1299  os << indent << "IORegion: " << std::endl;
1300  m_IORegion.Print(os, indent.GetNextIndent());
1301  os << indent << "Number of Components/Pixel: " << m_NumberOfComponents << "\n";
1302  os << indent << "Pixel Type: " << this->GetPixelTypeAsString(m_PixelType) << std::endl;
1303  os << indent << "Component Type: " << this->GetComponentTypeAsString(m_ComponentType)
1304  << std::endl;
1305  os << indent << "Dimensions: ( ";
1306  for (unsigned int i=0; i < m_NumberOfDimensions; i++)
1307  {
1308  os << m_Dimensions[i] << " ";
1309  }
1310  os << ")" << std::endl;
1311  os << indent << "Origin: ( ";
1312  for (unsigned int i=0; i < m_NumberOfDimensions; i++)
1313  {
1314  os << m_Origin[i] << " ";
1315  }
1316  os << ")" << std::endl;
1317 
1318  if (m_UseCompression)
1319  {
1320  os << indent << "UseCompression: On" << std::endl;
1321  }
1322  else
1323  {
1324  os << indent << "UseCompression: Off" << std::endl;
1325  }
1327  {
1328  os << indent << "UseStreamedReading: On" << std::endl;
1329  }
1330  else
1331  {
1332  os << indent << "UseStreamedReading: Off" << std::endl;
1333  }
1335  {
1336  os << indent << "UseStreamedWriting: On" << std::endl;
1337  }
1338  else
1339  {
1340  os << indent << "UseStreamedWriting: Off" << std::endl;
1341  }
1342 }
1343 
1344 } //namespace itk

Generated at Sat May 18 2013 23:43:47 for Orfeo Toolbox with doxygen 1.8.3.1