DGtal 1.4.0
Loading...
Searching...
No Matches
LongvolReader.ih
1/**
2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *
15 **/
16
17/**
18 * @file LongvolReader.ih
19 * @author David Coeurjolly (\c david.coeurjolly@liris.cnrs.fr )
20 * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
21 *
22 * @date 2011/06/11b
23 *
24 * Implementation of inline methods defined in LongvolReader.h
25 *
26 * This file is part of the DGtal library.
27 */
28
29
30//////////////////////////////////////////////////////////////////////////////
31#include <cstdlib>
32#include <boost/iostreams/filtering_streambuf.hpp>
33#include <boost/iostreams/copy.hpp>
34#include <boost/iostreams/filter/zlib.hpp>
35//////////////////////////////////////////////////////////////////////////////
36
37
38//! Maximum number of fields in a .longvol file header
39#define MAX_HEADERNUMLINES 64
40
41
42///////////////////////////////////////////////////////////////////////////////
43// Interface - public :
44template <typename T, typename TFunctor>
45inline
46T
47DGtal::LongvolReader<T, TFunctor>::importLongvol( const std::string & filename,
48 const Functor & aFunctor)
49{
50 FILE * fin;
51 DGtal::IOException dgtalexception;
52
53
54 typename T::Point firstPoint( 0, 0, 0 );
55 typename T::Point lastPoint( 0, 0, 0 );
56 T nullImage( typename T::Domain(firstPoint, lastPoint ));
57
58 HeaderField header[ MAX_HEADERNUMLINES ];
59
60 fin = fopen( filename.c_str() , "rb" );
61
62 if ( fin == NULL )
63 {
64 trace.error() << "LongvolReader : can't open " << filename << std::endl;
65 throw dgtalexception;
66 }
67
68
69 // Read header
70 // Buf for a line
71 char buf[128];
72 int linecount = 1;
73 int fieldcount = 0;
74
75 // Read the file line by line until ".\n" is found
76 for ( char *line = fgets( buf, 128, fin );
77 line && strcmp( line, ".\n" ) != 0 ;
78 line = fgets( line, 128, fin ), ++linecount
79 )
80 {
81
82 if ( line[strlen( line ) - 1] != '\n' )
83 {
84 trace.error() << "LongvolReader: Line " << linecount << " too long" << std::endl;
85 throw dgtalexception;
86 }
87
88 int i;
89 for ( i = 0; line[i] && line[i] != ':'; ++i )
90 ;
91
92 if ( i == 0 || i >= 126 || line[i] != ':' )
93 {
94 trace.error() << "LongvolReader: Invalid header read at line " << linecount << std::endl;
95 throw dgtalexception;
96 }
97 else
98 {
99
100 if ( fieldcount == MAX_HEADERNUMLINES )
101 {
102 trace.warning() << "LongvolReader: Too many lines in HEADER, ignoring\n";
103 continue;
104 }
105 if ( fieldcount > MAX_HEADERNUMLINES )
106 continue;
107
108 // Remove \n from end of line
109 if ( line[ strlen( line ) - 1 ] == '\n' )
110 line[ strlen( line ) - 1 ] = 0;
111
112 // hack : split line in two str ...
113 line[i] = 0;
114 header[ fieldcount++ ] = HeaderField( line, line + i + 2 );
115 // +2 cause we skip the space
116 // following the colon
117 }
118 }
119
120 // Check required headers
121 for ( int i = 0; requiredHeaders[i]; ++i )
122 {
123 if ( getHeaderValue( "Version" , header ) != NULL &&
124 ( strcmp( requiredHeaders[i], "Int-Endian" ) == 0 ||
125 strcmp( requiredHeaders[i], "Lvoxel-Endian" ) == 0 ) )
126 {
127 continue;
128 }
129 if ( getHeaderField( requiredHeaders[i] , header ) == -1 )
130 {
131 trace.error() << "LongvolReader: Required Header Field missing: "
132 << requiredHeaders[i] << std::endl;
133 throw dgtalexception;
134
135 }
136 }
137
138 int sx = 0, sy = 0, sz=0;
139 int cx = 0, cy = 0, cz=0;
140 int version = -1;
141 getHeaderValueAsInt( "X", &sx, header );
142 getHeaderValueAsInt( "Y", &sy, header );
143 getHeaderValueAsInt( "Z", &sz, header );
144 getHeaderValueAsInt( "Version", &version, header);
145
146 if (! ((version == 2) || (version == 3)))
147 {
148 trace.error() << "LongvolReader: invalid Version header (must be either 2 or 3)\n";
149 throw dgtalexception;
150 }
151
152
153 //Raw Data
154 if( getHeaderValueAsInt( "Center-X", &cx, header ) == 0 )
155 {
156 getHeaderValueAsInt( "Center-Y", &cy, header );
157 getHeaderValueAsInt( "Center-Z", &cz, header );
158
159 firstPoint[0] = cx - (sx - 1)/2;
160 firstPoint[1] = cy - (sy - 1)/2;
161 firstPoint[2] = cz - (sz - 1)/2;
162 lastPoint[0] = cx + sx/2;
163 lastPoint[1] = cy + sy/2;
164 lastPoint[2] = cz + sz/2;
165 }
166 else
167 {
168 firstPoint = T::Point::zero;
169 lastPoint[0] = sx - 1;
170 lastPoint[1] = sy - 1;
171 lastPoint[2] = sz - 1;
172 }
173 typename T::Domain domain( firstPoint, lastPoint );
174
175 try
176 {
177 T image( domain);
178
179 size_t count = 0;
180 DGtal::uint64_t val=0;
181
182 typename T::Domain::ConstIterator it = domain.begin();
183 size_t total = sx * sy * sz ;
184 size_t totalbytes = total * sizeof(val);
185 std::stringstream main;
186
187 unsigned char c_temp;
188 while (( count < totalbytes ) && ( fin ) )
189 {
190 c_temp = getc( fin );
191 main << c_temp;
192 count++;
193 }
194
195 if ( count != totalbytes )
196 {
197 trace.error() << "LongvolReader: can't read file (raw data). I read "<<count<<" bytes instead of "<<total<<".\n";
198 throw dgtalexception;
199 }
200
201 //Uncompress if needed
202 if(version == 3)
203 {
204 std::stringstream uncompressed;
205 boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
206 in.push(boost::iostreams::zlib_decompressor());
207 in.push(main);
208 boost::iostreams::copy(in, uncompressed);
209 //Apply to the image structure
210 for(size_t i=0; i < total; ++i)
211 {
212 read_word(uncompressed , val);
213 image.setValue(( *it ), aFunctor(val) );
214 it++;
215 }
216 }
217 else
218 {
219 //Apply to the image structure
220 for(size_t i=0; i < total; ++i)
221 {
222 read_word(main, val);
223 image.setValue(( *it ), aFunctor(val) );
224 it++;
225 }
226 }
227 fclose( fin );
228 return image;
229 }
230 catch ( ... )
231 {
232 trace.error() << "LongvolReader: not enough memory\n" ;
233 throw dgtalexception;
234 }
235
236 }
237
238
239
240 template <typename T, typename TFunctor>
241 const char *DGtal::LongvolReader<T, TFunctor>::requiredHeaders[] =
242 {
243 "X", "Y", "Z", "Lvoxel-Size", "Int-Endian", "Lvoxel-Endian", "Alpha-Color", NULL
244 };
245
246
247
248
249 template<typename T, typename TFunctor>
250 inline
251 int
252 DGtal::LongvolReader<T,TFunctor>::getHeaderField( const char *type, const HeaderField * header )
253 {
254
255
256 for ( int i = 0; i < MAX_HEADERNUMLINES; ++i )
257 {
258 if ( header[i].type != NULL && strcmp( header[i].type, type ) == 0 )
259 {
260 return i;
261 }
262 }
263 return -1;
264 }
265
266
267 template<typename T, typename TFunctor>
268 inline
269 const char *
270 DGtal::LongvolReader<T, TFunctor>::getHeaderValue( const char *type, const HeaderField * header )
271 {
272
273 int i = getHeaderField( type, header );
274 if ( i == -1 )
275 return NULL;
276 return header[i].value;
277
278 }
279
280
281 template<typename T, typename TFunctor>
282 inline
283 int
284 DGtal::LongvolReader<T, TFunctor>::getHeaderValueAsInt( const char *type, int *dest, const HeaderField * header )
285 {
286 int i = getHeaderField( type, header );
287 if ( i == -1 )
288 return 1;
289
290 return sscanf( header[i].value, "%d", dest ) == 0;
291 }
292