1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 
19 #include <fstream>
20 #include "itkRawImageIO.h"
21 #include "itkImageFileReader.h"
22 #include "itkImageLinearIteratorWithIndex.h"
23 
24 
25 // Specific ImageIO test
26 
27 
28 // Helper class for reading a file and checking the content
29 template< typename TImageType >
30 class RawImageIOReadFileTester
31 {
32 public:
33 // Only single method of this class
Read(const char * filename,bool ReadBigEndian,unsigned int dims[])34 int Read( const char *filename , bool ReadBigEndian, unsigned int dims[] )
35   {
36 
37     const unsigned int ImageDimension = TImageType::ImageDimension;
38 
39     using PixelType = typename TImageType::PixelType;
40     using ReaderType = itk::ImageFileReader<TImageType>;
41     using IOType = itk::RawImageIO<PixelType,ImageDimension>;
42 
43     typename IOType::Pointer io = IOType::New();
44 
45     io->SetFileTypeToBinary();
46 
47     if( ReadBigEndian )
48       {
49       io->SetByteOrderToBigEndian();
50       }
51     else
52       {
53       io->SetByteOrderToLittleEndian();
54       }
55 
56     for( unsigned int j = 0; j < TImageType::ImageDimension; j++ )
57       {
58       io->SetDimensions( j, dims[j] );
59       }
60 
61     typename ReaderType::Pointer reader = ReaderType::New();
62     reader->SetFileName( filename );
63     reader->SetImageIO( io );
64 
65     try
66       {
67       reader->Update();
68       }
69     catch( itk::ExceptionObject & excp )
70       {
71       std::cerr << "Exception while reading file " << filename << std::endl;
72       std::cerr << excp << std::endl;
73       return EXIT_FAILURE;
74       }
75 
76     std::cout << "Reading file " << filename << " succeeded " << std::endl;
77 
78     using Iterator = itk::ImageLinearIteratorWithIndex<TImageType>;
79     Iterator it( reader->GetOutput(), reader->GetOutput()->GetBufferedRegion() );
80 
81     it.GoToBegin();
82     it.SetDirection( 0 );
83 
84 
85     PixelType value = itk::NumericTraits< PixelType >::ZeroValue();
86     while ( !it.IsAtEnd() )
87       {
88       while ( !it.IsAtEndOfLine() )
89         {
90         PixelType readValue = it.Get();
91         std::cout << readValue << " ";
92         if( readValue != value )
93           {
94           std::cerr << "At index " << it.GetIndex() << std::endl;
95           std::cerr << "the value " << value << " was expected  " << std::endl;
96           std::cerr << "but value " << readValue << " was read  " << std::endl;
97           return EXIT_FAILURE;
98           }
99         ++it;
100         ++value;
101         }
102       std::cout << std::endl;
103       it.NextLine();
104       }
105     return EXIT_SUCCESS;
106   }
107 
108 };
109 
itkRawImageIOTest4(int argc,char * argv[])110 int itkRawImageIOTest4(int argc, char*argv[])
111 {
112 
113   using PixelType = unsigned short;
114   constexpr unsigned int ImageDimension = 2;
115 
116   using ImageType = itk::Image<PixelType,ImageDimension>;
117 
118   unsigned int dims[ImageDimension] = { 5, 5 };
119 
120   using ComponentType = itk::PixelTraits< PixelType >::ValueType;
121   using ByteSwapperType = itk::ByteSwapper< ComponentType >;
122 
123   PixelType value = itk::NumericTraits< PixelType >::ZeroValue();
124   unsigned int numberOfPixels = dims[0] * dims[1];
125 
126   if(argc < 3)
127     {
128     std::cerr << "Usage: " << argv[0] << " Output1 Output2\n";
129     return EXIT_FAILURE;
130     }
131 
132 
133   // Create the BigEndian binary file
134   std::ofstream outputFile1(argv[1], std::ios::out);
135   outputFile1.close();
136 #ifdef _WIN32
137   outputFile1.open( argv[1] , std::ios::out | std::ios::binary );
138 #else
139   outputFile1.open( argv[1] );
140 #endif
141 
142   if( outputFile1.fail() )
143     {
144     std::cerr << "itkRawImageIOTest4:Error writing the test file" << std::endl;
145     return EXIT_FAILURE;
146     }
147 
148   for( unsigned int i = 0; i < numberOfPixels; i++ )
149     {
150     PixelType swappedValue = value;
151     // make sure that the file is written in
152     // BigEndian regardless of the platform
153     ByteSwapperType::SwapFromSystemToBigEndian( &swappedValue );
154     outputFile1.write( reinterpret_cast<char*>(&swappedValue),
155                       sizeof(swappedValue) );
156     ++value;
157     }
158   outputFile1.close();
159 
160   if( outputFile1.fail() )
161     {
162     std::cerr << "itkRawImageIOTest4:Error writing the test file" << std::endl;
163     return EXIT_FAILURE;
164     }
165 
166   // Create the LittleEndian binary file
167   std::ofstream outputFile2(argv[2], std::ios::out);
168   outputFile2.close();
169 #ifdef _WIN32
170   outputFile2.open( argv[2] , std::ios::out | std::ios::binary );
171 #else
172   outputFile2.open( argv[2] );
173 #endif
174 
175   if( outputFile2.fail() )
176     {
177     std::cerr << "itkRawImageIOTest4:Error writing the test file" << std::endl;
178     return EXIT_FAILURE;
179     }
180 
181   value = itk::NumericTraits< PixelType >::ZeroValue();
182   for( unsigned int i = 0; i < numberOfPixels; i++ )
183     {
184     PixelType swappedValue = value;
185     // make sure that the file is written in
186     // LittleEndian regardless of the platform
187     ByteSwapperType::SwapFromSystemToLittleEndian( &swappedValue );
188     outputFile2.write( reinterpret_cast<char*>(&swappedValue),
189                       sizeof(swappedValue) );
190     ++value;
191     }
192   outputFile2.close();
193 
194   if( outputFile2.fail() )
195     {
196     std::cerr << "itkRawImageIOTest4:Error writing the test file" << std::endl;
197     return EXIT_FAILURE;
198     }
199 
200   RawImageIOReadFileTester<ImageType>  readTester;
201 
202 
203   int status;
204 
205   std::cout << "Testing read of Big Endian File" << std::endl;
206   bool fileIsBigEndian = true;
207   status = readTester.Read( argv[1], fileIsBigEndian, dims );
208   if( status==EXIT_FAILURE )
209     {
210     std::cerr << "Reading Raw BigEndian FAILED !!" << std::endl;
211     return EXIT_FAILURE;
212     }
213   else
214     {
215     std::cout << "Reading Raw BigEndian PASSED !!" << std::endl << std::endl;
216     }
217 
218   std::cout << "Testing read of Little Endian File" << std::endl;
219   fileIsBigEndian = false;
220   status = readTester.Read( argv[2], fileIsBigEndian, dims );
221   if( status==EXIT_FAILURE )
222     {
223     std::cerr << "Reading Raw LittleEndian FAILED !!" << std::endl;
224     return EXIT_FAILURE;
225     }
226   else
227     {
228     std::cout << "Reading Raw LittleEndian PASSED !!" << std::endl << std::endl;
229     }
230 
231   std::cout << "Test PASSED !!" << std::endl << std::endl;
232 
233   return EXIT_SUCCESS;
234 
235 }
236