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