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