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  * \file   itkIPLCommonImageIO.h
20  *         Much of the code for this file reader/writer was taken from
21  *         the University of Iowa Imaging Group library with the
22  *         permission of the authors, Milan Sonka, Joseph Reinhardt,
23  *         Ryan Long, Hans Johnson, Gary Christensen, and others.
24  *         The specification for this file format is taken from the
25  *         web site http://analyzedirect.com/support/10.0Documents/Analyze_Resource_01.pdf
26  * \author Kent Williams
27  *         The University of Iowa 2003
28  * \brief This file was written as a modification to the itkMetaImageIO
29  *        as a new method for reading in files from the GE4 scanner.
30  */
31 
32 #ifndef itkIPLCommonImageIO_h
33 #define itkIPLCommonImageIO_h
34 #include "ITKIOIPLExport.h"
35 
36 #include "itkImageIOBase.h"
37 #include "itkIPLFileNameList.h"
38 #include "itkGEImageHeader.h"
39 
40 namespace itk
41 {
42 /** \class IPLCommonImageIO
43   *
44   * \author Hans J. Johnson
45   * \brief Class that defines how to read GE4 file format.
46   *
47   * \ingroup IOFilters
48   * \ingroup ITKIOIPL
49   */
50 class ITKIOIPL_EXPORT IPLCommonImageIO:public ImageIOBase
51 {
52 public:
53   ITK_DISALLOW_COPY_AND_ASSIGN(IPLCommonImageIO);
54 
55   /** Standard class type aliases. */
56   using Self = IPLCommonImageIO;
57   using Superclass = ImageIOBase;
58   using Pointer = SmartPointer< Self >;
59 
60   using U8 = unsigned char;
61   using S8 = signed char;
62   using U16 = unsigned short;
63   using S16 = signed short;
64   using U32 = unsigned int;
65   using S32 = signed int;
66   using U64 = uint64_t;
67   using S64 = int64_t;
68   using F32 = float;
69   using F64 = double;
70 
71   /** Method for creation through the object factory. */
72   itkNewMacro(Self);
73 
74   /** Run-time type information (and related methods). */
75   itkTypeMacro(IPLCommonImageIO, Superclass);
76 
77   /*-------- This part of the interfaces deals with reading data. ----- */
78 
79   /** Determine if the file can be read with this ImageIO implementation.
80     * \author Hans J Johnson
81     * \param FileNameToRead The name of the file to test for reading.
82     * \post Sets classes ImageIOBase::m_FileName variable to be FileNameToWrite
83     * \return Returns true if this ImageIO can read the file specified.
84     */
85   bool CanReadFile(const char *FileNameToRead) override;
86 
87   /** Set the spacing and dimension information for the set filename. */
88   void ReadImageInformation() override;
89 
90   /** Optionally, modify spacing, origin and direction */
ModifyImageInformation()91   virtual void ModifyImageInformation() {}
92 
93   /** Reads the data from disk into the memory buffer provided. */
94   void Read(void *buffer) override;
95 
96   /** Compute the size (in bytes) of the components of a pixel. For
97        * example, and RGB pixel of unsigned char would have a
98        * component size of 1 byte. */
99   unsigned int GetComponentSize() const override;
100 
101   /*-------- This part of the interfaces deals with writing data. ----- */
102 
103   /** Determine if the file can be written with this ImageIO implementation.
104        * \param FileNameToWrite The name of the file to test for writing.
105        * \author Hans J. Johnson
106        * \post Sets classes ImageIOBase::m_FileName variable to be FileNameToWrite
107        * \return Returns true if this ImageIO can write the file specified.
108        */
109   bool CanWriteFile(const char *FileNameToWrite) override;
110 
111   /** Set the spacing and dimension information for the set filename. */
112   void WriteImageInformation() override;
113 
114   /** Writes the data to disk from the memory buffer provided. Make sure
115        * that the IORegions has been set properly. */
116   void Write(const void *buffer) override;
117 
118   /** Set sorting method by name ascending. */
119   virtual void SortImageListByNameAscend();
120 
121   /** Set sorting method by name descending. */
122   virtual void SortImageListByNameDescend();
123 
124 protected:
125   IPLCommonImageIO();
126   ~IPLCommonImageIO() override;
127   void PrintSelf(std::ostream & os, Indent indent) const override;
128 
129   int AddElementToList(char const *const filename,
130                        const float sliceLocation,
131                        const int offset,
132                        const int XDim,
133                        const int YDim,
134                        const float XRes,
135                        const float YRes,
136                        const int Key1,
137                        const int Key2);
138 
139   void sortImageListAscend();
140 
141   void sortImageListDescend();
142 
143   int statTimeToAscii(void *clock, char *timeString, int len);
144 
145   virtual GEImageHeader * ReadHeader(const char *FileNameToRead);
146 
147   //
148   // data members
149   GEImageHeader         *m_ImageHeader;
150   ImageIOBase::ByteOrder m_SystemByteOrder;
151   IPLFileNameList       *m_FilenameList;
152   //
153   // return 0 on success, -1 on failure
154   int GetStringAt(std::ifstream & f, std::streamoff Offset, char *buf,
155                   size_t amount, bool throw_exception = true);
156 
157   int GetIntAt(std::ifstream & f, std::streamoff Offset, int *ip,
158                bool throw_exception = true);
159 
160   int GetShortAt(std::ifstream & f, std::streamoff Offset, short *ip,
161                  bool throw_exception = true);
162 
163   int GetFloatAt(std::ifstream & f, std::streamoff Offset, float *ip,
164                  bool throw_exception = true);
165 
166   int GetDoubleAt(std::ifstream & f, std::streamoff Offset, double *ip,
167                   bool throw_exception = true);
168 
169   short hdr2Short(char *hdr);
170 
171   int hdr2Int(char *hdr);
172 
173   float hdr2Float(char *hdr);
174 
175   double hdr2Double(char *hdr);
176 };
177 } // end namespace itk
178 #define RAISE_EXCEPTION()                                    \
179             { ExceptionObject exception(__FILE__, __LINE__); \
180             exception.SetDescription("File cannot be read"); \
181             throw exception; }
182 
183 #define IOCHECK()      \
184   if ( f.fail() )      \
185     {                  \
186     if ( f.is_open() ) \
187       {                \
188       f.close();       \
189       }                \
190     RAISE_EXCEPTION(); \
191     }
192 
193 #endif // itkIPLCommonImageIO_h
194