DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
VolReader.ih
1 
30 
31 #include <cstdlib>
33 
34 
36 // Interface - public :
37 
38 
39 
40 
41 template <typename T>
42 inline
43 T
44 DGtal::VolReader<T>::importVol( const std::string & filename ) throw( DGtal::IOException )
45 {
46  FILE * fin;
47  DGtal::IOException dgtalexception;
48 
49 
50  typename T::Point firstPoint( 0, 0, 0 );
51  typename T::Point lastPoint( 0, 0, 0 );
52  T nullImage( typename T::Domain( firstPoint, lastPoint ));
53 
54  HeaderField header[ MAX_HEADERNUMLINES ];
55 
56 #ifdef WIN32
57  errno_t err;
58  err = fopen_s( &fin, filename.c_str() , "r" );
59  if ( err )
60  {
61  trace.error() << "VolReader : can't open " << filename << endl;
62  throw dgtalexception;
63  }
64 #else
65  fin = fopen( filename.c_str() , "r" );
66 #endif
67 
68  if ( fin == NULL )
69  {
70  trace.error() << "VolReader : can't open " << filename << endl;
71  throw dgtalexception;
72  }
73 
74 
75  // Read header
76  // Buf for a line
77  char buf[128];
78  int linecount = 1;
79  int fieldcount = 0;
80 
81  // Read the file line by line until ".\n" is found
82  for ( char *line = fgets( buf, 128, fin );
83  line && strcmp( line, ".\n" ) != 0 ;
84  line = fgets( line, 128, fin ), ++linecount
85  )
86  {
87 
88  if ( line[strlen( line ) - 1] != '\n' )
89  {
90  trace.error() << "VolReader: Line " << linecount << " too long" << std::endl;
91  throw dgtalexception;
92  }
93 
94  int i;
95  for ( i = 0; line[i] && line[i] != ':'; ++i )
96  ;
97 
98  if ( i == 0 || i >= 126 || line[i] != ':' )
99  {
100  trace.error() << "VolReader: Invalid header read at line " << linecount << std::endl;
101  throw dgtalexception;
102  }
103  else
104  {
105 
106  if ( fieldcount == MAX_HEADERNUMLINES )
107  {
108  trace.warning() << "VolReader: Too many lines in HEADER, ignoring\n";
109  continue;
110  }
111  if ( fieldcount > MAX_HEADERNUMLINES )
112  continue;
113 
114  // Remove \n from end of line
115  if ( line[ strlen( line ) - 1 ] == '\n' )
116  line[ strlen( line ) - 1 ] = 0;
117 
118  // hack : split line in two str ...
119  line[i] = 0;
120  header[ fieldcount++ ] = HeaderField( line, line + i + 2 );
121  // +2 cause we skip the space
122  // following the colon
123  }
124  }
125 
126  // Check required headers
127  for ( int i = 0; requiredHeaders[i]; ++i )
128  {
129  if ( getHeaderValue( "Version" , header ) != NULL &&
130  ( strcmp( requiredHeaders[i], "Int-Endian" ) == 0 ||
131  strcmp( requiredHeaders[i], "Voxel-Endian" ) == 0 ) )
132  {
133  continue;
134  }
135  if ( getHeaderField( requiredHeaders[i] , header ) == -1 )
136  {
137  trace.error() << "VolReader: Required Header Field missing: "
138  << requiredHeaders[i] << std::endl;
139  throw dgtalexception;
140 
141  }
142  }
143 
144  int sx, sy, sz;
145 
146  getHeaderValueAsInt( "X", &sx, header );
147  getHeaderValueAsInt( "Y", &sy, header );
148  getHeaderValueAsInt( "Z", &sz, header );
149 
150  if ( getHeaderValue( "Version", header ) == NULL )
151  {
152  int rawsx, rawsy, rawsz;
153  long int count = 0;
154  // Size of the volume
155  count += (long)fread( &rawsx, sizeof( int ), 1, fin );
156  count += (long)fread( &rawsy, sizeof( int ), 1, fin );
157  count += (long)fread( &rawsz, sizeof( int ), 1, fin );
158 
159  if ( count != 3 )
160  {
161  trace.error() << "VolReader: can't read file (raw header)\n";
162  throw dgtalexception;
163  }
164 
165 
166  if ( sx != rawsx || sy != rawsy || sz != rawsz )
167  {
168  trace.warning() << "VolReader: Warning : Incoherent vol header with raw header !\n";
169  }
170 
171  int voxsize;
172  if ( getHeaderValueAsInt( "Voxel-Size", &voxsize, header ) == 0 && voxsize != sizeof( voxel ) )
173  {
174  trace.error() << "VolReader: This file was generated with a voxel-size that we do not support.\n";
175  throw dgtalexception;
176  }
177 
178  // We should have a useless \n in the file at this point
179  char tmp;
180  count = (long)fread( &tmp, sizeof( char ), 1, fin );
181 
182  if ( count != 1 || tmp != '\n' )
183  {
184  trace.error() << "VolReader: I thouhgt I would have read a \\n !\n";
185  throw dgtalexception;
186  }
187  }
188 
189  //Raw Data
190  long count = 0;
191 
192  firstPoint = T::Point::zero;
193  lastPoint[0] = sx - 1;
194  lastPoint[1] = sy - 1;
195  lastPoint[2] = sz - 1;
196  typename T::Domain domain( firstPoint, lastPoint );
197 
198  try
199  {
200  T image( domain );
201 
202  count = 0;
203  unsigned char val;
204  typename T::Domain::ConstIterator it = domain.begin();
205  long int total = sx * sy * sz;
206 
207  while (( count < total ) && ( fin ) )
208  {
209  val = getc( fin );
210  image.setValue(( *it ), val );
211  it++;
212  count++;
213  }
214 
215  if ( count != total )
216  {
217  trace.error() << "VolReader: can't read file (raw data) !\n";
218  throw dgtalexception;
219  }
220 
221  fclose( fin );
222  return image;
223  }
224  catch ( ... )
225  {
226  trace.error() << "VolReader: not enough memory\n" ;
227  throw dgtalexception;
228  }
229 
230 }
231 
232 
233 
234 template <typename T>
236 {
237  "X", "Y", "Z", "Voxel-Size", "Int-Endian", "Voxel-Endian", "Alpha-Color", NULL
238 };
239 
240 
241 
242 
243 template<typename T>
244 inline
245 int
246 DGtal::VolReader<T>::getHeaderField( const char *type, const HeaderField * header )
247 {
248 
249 
250  for ( int i = 0; i < MAX_HEADERNUMLINES; ++i )
251  {
252  if ( header[i].type != NULL && strcmp( header[i].type, type ) == 0 )
253  {
254  return i;
255  }
256  }
257  return -1;
258 }
259 
260 
261 template<typename T>
262 inline
263 const char *
264 DGtal::VolReader<T>::getHeaderValue( const char *type, const HeaderField * header )
265 {
266 
267  int i = getHeaderField( type, header );
268  if ( i == -1 )
269  return NULL;
270  return header[i].value;
271 
272 }
273 
274 
275 template<typename T>
276 inline
277 int
278 DGtal::VolReader<T>::getHeaderValueAsInt( const char *type, int *dest, const HeaderField * header )
279 {
280  int i = getHeaderField( type, header );
281  if ( i == -1 )
282  return 1;
283 
284  return sscanf( header[i].value, "%d", dest ) != 0;
285 }
286