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 "itkNiftiImageIOTest.h"
20 
21 //The WriteNiftiTestFiles function writes binary data to disk to ensure that both big and little endian files are available.
22 //This allows all the data necessary to create the images to be stored in source files rather than have separate reference images.
WriteNiftiTestFiles(const std::string & prefix)23 int WriteNiftiTestFiles(const std::string & prefix)
24 {
25 #include "LittleEndian_hdr.h"
26     struct nifti_1_header NiftiLittleEndian;
27     memcpy(&NiftiLittleEndian,LittleEndian_hdr,sizeof(NiftiLittleEndian));
28     NiftiLittleEndian.qform_code=NIFTI_XFORM_UNKNOWN;
29     NiftiLittleEndian.sform_code=NIFTI_XFORM_UNKNOWN;
30     strncpy(NiftiLittleEndian.magic,"ni1\0",4);
31 #include "LittleEndian_img.h"
32 #include "BigEndian_hdr.h"
33     struct nifti_1_header NiftiBigEndian;
34     memcpy(&NiftiBigEndian,BigEndian_hdr,sizeof(NiftiBigEndian));
35     NiftiBigEndian.qform_code=NIFTI_XFORM_UNKNOWN;
36     NiftiBigEndian.sform_code=NIFTI_XFORM_UNKNOWN;
37     strncpy(NiftiBigEndian.magic,"ni1\0",4);
38 #include "BigEndian_img.h"
39 #include "itkMath.h"
40     //Force to be Nifti-compliant
41   std::ofstream little_hdr((prefix+"NiftiLittleEndian.hdr").c_str(), std::ios::binary | std::ios::out);
42   if(!little_hdr.is_open())
43     return EXIT_FAILURE;
44   std::cout << "NiftiLittleEndian written" << std::endl;
45   little_hdr.write(reinterpret_cast<const char *>(LittleEndian_hdr),sizeof(LittleEndian_hdr));
46   little_hdr.close();
47   std::ofstream little_img((prefix+"NiftiLittleEndian.img").c_str(), std::ios::binary | std::ios::out);
48   if(!little_img.is_open())
49     return EXIT_FAILURE;
50   little_img.write(reinterpret_cast<const char *>(LittleEndian_img),sizeof(LittleEndian_img));
51   little_img.close();
52   std::ofstream big_hdr((prefix+"NiftiBigEndian.hdr").c_str(), std::ios::binary | std::ios::out);
53   if(!big_hdr.is_open())
54     return EXIT_FAILURE;
55   big_hdr.write(reinterpret_cast<const char *>(BigEndian_hdr),sizeof(BigEndian_hdr));
56   big_hdr.close();
57   std::ofstream big_img((prefix+"NiftiBigEndian.img").c_str(), std::ios::binary | std::ios::out);
58   if(!big_img.is_open())
59     return EXIT_FAILURE;
60   big_img.write(reinterpret_cast<const char *>(BigEndian_img),sizeof(BigEndian_img));
61   big_img.close();
62   return EXIT_SUCCESS;
63 }
64 
TestNiftiByteSwap(const std::string & prefix)65 int TestNiftiByteSwap(const std::string & prefix)
66 {
67   int rval;
68   using ImageType = itk::Image<double, 3>;
69   if(WriteNiftiTestFiles(prefix) == -1)
70     {
71       return EXIT_FAILURE;
72     }
73 
74   ImageType::Pointer little;
75   ImageType::Pointer big;
76 
77   try
78     {
79     little = itk::IOTestHelper::ReadImage<ImageType>(prefix+"NiftiLittleEndian.hdr", false);
80     const std::string fname(prefix+"NiftiBigEndian.hdr");
81     big = itk::IOTestHelper::ReadImage<ImageType>(fname, false);
82     std::cout << "Printing Dictionary" << std::endl;
83     big->GetMetaDataDictionary().Print(std::cout);
84     }
85   catch (itk::ExceptionObject &e)
86     {
87     e.Print(std::cerr);
88     RemoveNiftiByteSwapTestFiles(prefix);
89     return EXIT_FAILURE;
90     }
91   rval = 0;
92   try
93     {
94       itk::ImageRegionConstIterator<ImageType> littleIter(little,
95                                                           little->GetLargestPossibleRegion());
96       itk::ImageRegionConstIterator<ImageType> bigIter(big,
97                                                        big->GetLargestPossibleRegion());
98       while(!littleIter.IsAtEnd())
99         {
100           if(itk::Math::NotExactlyEquals(littleIter.Get(), bigIter.Get()))
101             break;
102           ++littleIter;
103           ++bigIter;
104         }
105       if(!littleIter.IsAtEnd() || !bigIter.IsAtEnd())
106         rval = -1;
107     }
108   catch ( itk::ExceptionObject & ex )
109     {
110       std::cerr << "Error filling array" << ex << std::endl;
111       rval= -1;
112     }
113 
114   RemoveNiftiByteSwapTestFiles(prefix);
115   return rval;
116 }
117 
RemoveNiftiByteSwapTestFiles(const std::string & prefix)118 void RemoveNiftiByteSwapTestFiles(const std::string & prefix)
119 {
120   itk::IOTestHelper::Remove((prefix+"NiftiLittleEndian.hdr").c_str());
121   itk::IOTestHelper::Remove((prefix+"NiftiLittleEndian.img").c_str());
122   itk::IOTestHelper::Remove((prefix+"NiftiBigEndian.hdr").c_str());
123   itk::IOTestHelper::Remove((prefix+"NiftiBigEndian.img").c_str());
124 }
125