Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
tiff/load.hh
1 // Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_IO_TIFF_LOAD_HH
27 # define MLN_IO_TIFF_LOAD_HH
28 
29 
37 
38 
39 # include <iostream>
40 # include <fstream>
41 # include <tiffio.h>
42 
43 # include <mln/core/concept/image.hh>
44 # include <mln/value/rgb8.hh>
45 
46 
47 
48 namespace mln
49 {
50 
51  namespace io
52  {
53 
54  namespace tiff
55  {
56 
57 
59  //
60  template <typename I>
61  void load(Image<I>& ima_, const std::string& filename);
62 
63 
64 
65 # ifndef MLN_INCLUDE_ONLY
66 
67 
68  namespace internal
69  {
70 
71  inline
72  point2d ij2rc_1(int i, int j, int ni_1, int nj_1)
73  {
74  (void) nj_1;
75  return point2d(ni_1 - i, j);
76  }
77 
78  inline
79  point2d ij2rc_2(int i, int j, int ni_1, int nj_1)
80  {
81  return point2d(ni_1 - i, nj_1 - j);
82  }
83 
84  inline
85  point2d ij2rc_3(int i, int j, int ni_1, int nj_1)
86  {
87  (void) ni_1;
88  return point2d(i, nj_1 - j);
89  }
90 
91  inline
92  point2d ij2rc_4(int i, int j, int ni_1, int nj_1)
93  {
94  (void) ni_1;
95  (void) nj_1;
96  return point2d(i, j);
97  }
98 
99  inline
100  point2d ij2rc_5(int i, int j, int ni_1, int nj_1)
101  {
102  (void) nj_1;
103  return point2d(j, ni_1 - i);
104  }
105 
106  inline
107  point2d ij2rc_6(int i, int j, int ni_1, int nj_1)
108  {
109  return point2d(nj_1 - j, ni_1 - i);
110  }
111 
112  inline
113  point2d ij2rc_7(int i, int j, int ni_1, int nj_1)
114  {
115  (void) ni_1;
116  return point2d(nj_1 - j, i);
117  }
118 
119  inline
120  point2d ij2rc_8(int i, int j, int ni_1, int nj_1)
121  {
122  (void) ni_1;
123  (void) nj_1;
124  return point2d(j, i);
125  }
126 
127 
128 
129  template <typename I>
130  inline
131  I load_header(TIFF *file)
132  {
133  uint32 width, height;
134 
135  TIFFGetField(file, TIFFTAG_IMAGEWIDTH, &width);
136  TIFFGetField(file, TIFFTAG_IMAGELENGTH, &height);
137 
138  mln_concrete(I) new_ima(height, width, 0);
139 
140  return new_ima;
141  }
142 
143 
144  template <typename I>
145  inline
146  void load_data_rgb8(I& ima, TIFF *file)
147  {
148  uint16 bits_per_sample, samples_per_pixel;
149 
150  TIFFGetField(file, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
151  TIFFGetField(file, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
152 
153  uint16 data_size = bits_per_sample * samples_per_pixel;
154  if (data_size != 24 && data_size != 32)
155  {
156  std::cout << "Trying to load a non color TIFF "
157  << "image into a color Milena image." << std::endl;
158  abort();
159  }
160 
161  uint32 npixels = ima.ncols() * ima.nrows();
162  uint32 *raster = (uint32 *) _TIFFmalloc(npixels * sizeof (uint32));
163 
164  if (!TIFFReadRGBAImage(file, ima.ncols(), ima.nrows(), raster, 0))
165  {
166  std::cout << "Error while reading the image file. Is it corrupted?"
167  << std::endl;
168  abort();
169  }
170 
171  uint16 orientation;
172  TIFFGetField(file, TIFFTAG_ORIENTATION, &orientation);
173 
174  typedef point2d (*fun_t)(int, int, int, int);
175  fun_t funs[] = { 0, ij2rc_1, ij2rc_2, ij2rc_3, ij2rc_4,
176  ij2rc_5, ij2rc_6, ij2rc_7, ij2rc_8 };
177  fun_t fun = funs[orientation];
178 
179  int ni_1, nj_1;
180  unsigned idx = 0;
181 
182  if (orientation <= 4)
183  {
184  ni_1 = ima.nrows() - 1;
185  nj_1 = ima.ncols() - 1;
186  for (int i = 0; i <= ni_1; ++i)
187  for (int j = 0; j <= nj_1; ++j)
188  {
189  value::rgb8 v;
190 
191  v.red() = (unsigned char) TIFFGetR(raster[idx]);
192  v.green() = (unsigned char) TIFFGetG(raster[idx]);
193  v.blue() = (unsigned char) TIFFGetB(raster[idx]);
194  ima((*fun)(i, j, ni_1, nj_1)) = v;
195 
196  ++idx;
197  }
198  }
199  else
200  {
201  nj_1 = ima.nrows() - 1;
202  ni_1 = ima.ncols() - 1;
203  for (int j = 0; j <= nj_1; ++j)
204  for (int i = 0; i <= ni_1; ++i)
205  {
206  value::rgb8 v;
207 
208  v.red() = (unsigned char) TIFFGetR(raster[idx]);
209  v.green() = (unsigned char) TIFFGetG(raster[idx]);
210  v.blue() = (unsigned char) TIFFGetB(raster[idx]);
211  ima((*fun)(i, j, ni_1, nj_1)) = v;
212 
213  ++idx;
214  }
215  }
216 
217  _TIFFfree(raster);
218  }
219 
220 
221 
222 
223  template <typename I>
224  inline
225  void load_data_scalar(I& ima, TIFF *file)
226  {
227  uint16 samples_per_pixel;
228  TIFFGetField(file, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
229  if (samples_per_pixel != 1)
230  {
231  std::cout << "Trying to load a non grayscale TIFF "
232  << "image into a grayscale Milena image." << std::endl;
233  abort();
234  }
235 
236  uint32 npixels = ima.ncols() * ima.nrows();
237  uint32 *raster = (uint32 *) _TIFFmalloc(npixels * sizeof (uint32));
238 
239  if (!TIFFReadRGBAImage(file, ima.ncols(), ima.nrows(), raster, 0))
240  {
241  std::cout << "Error while reading the image file. Is it corrupted?"
242  << std::endl;
243  abort();
244  }
245 
246  uint16 orientation;
247  TIFFGetField(file, TIFFTAG_ORIENTATION, &orientation);
248 
249  typedef point2d (*fun_t)(int, int, int, int);
250  fun_t funs[] = { 0, ij2rc_1, ij2rc_2, ij2rc_3, ij2rc_4,
251  ij2rc_5, ij2rc_6, ij2rc_7, ij2rc_8 };
252  fun_t fun = funs[orientation];
253 
254  int ni_1, nj_1;
255  unsigned idx = 0;
256 
257  if (orientation <= 4)
258  {
259  ni_1 = ima.nrows() - 1;
260  nj_1 = ima.ncols() - 1;
261  for (int i = 0; i <= ni_1; ++i)
262  for (int j = 0; j <= nj_1; ++j)
263  {
264  ima((*fun)(i, j, ni_1, nj_1)) = (unsigned char) TIFFGetR(raster[idx++]);
265  }
266  }
267  else
268  {
269  nj_1 = ima.nrows() - 1;
270  ni_1 = ima.ncols() - 1;
271  for (int j = 0; j <= nj_1; ++j)
272  for (int i = 0; i <= ni_1; ++i)
273  {
274  ima((*fun)(i, j, ni_1, nj_1)) = (unsigned char) TIFFGetR(raster[idx++]);
275  }
276  }
277 
278  _TIFFfree(raster);
279  }
280 
281  template <typename I>
282  inline
283  void
284  load_data_dispatch(const value::rgb8&, I& ima, TIFF *file)
285  {
286  load_data_rgb8(ima, file);
287  }
288 
289  template <typename S, typename I>
290  inline
291  void
292  load_data_dispatch(const value::Scalar<S>&, I& ima, TIFF *file)
293  {
294  load_data_scalar(ima, file);
295  }
296 
297  template <typename I>
298  inline
299  void
300  load_data_dispatch(const bool&, I& ima, TIFF *file)
301  {
302  load_data_scalar(ima, file);
303  }
304 
305 
306  template <typename I>
307  inline
308  void
309  load_data_dispatch(I& ima, TIFF *file)
310  {
311  load_data_dispatch(mln_value(I)(), exact(ima), file);
312  }
313 
314 
315  } // end of namespace mln::io::tiff::internal
316 
317 
318 
319  // Facade
320 
321  template <typename I>
322  inline
323  void load(Image<I>& ima_, const std::string& filename)
324  {
325  trace::entering("mln::io::tiff::load");
326 
327  I& ima = exact(ima_);
328 
329  TIFF *file = TIFFOpen(filename.c_str(), "r");
330  if (file == 0)
331  {
332  std::cerr << "io::tiff::load - Error: cannot open file '"
333  << filename << "'!"
334  << std::endl;
335  abort();
336  }
337 
338  ima = internal::load_header<I>(file);
339  internal::load_data_dispatch(ima, file);
340 
341  mln_postcondition(ima.is_valid());
342 
343  (void) TIFFClose(file);
344  trace::exiting("mln::io::tiff::load");
345  }
346 
347 # endif // ! MLN_INCLUDE_ONLY
348 
349  } // end of namespace mln::io::tiff
350 
351  } // end of namespace mln::io
352 
353 } // end of namespace mln
354 
355 #endif // ! MLN_IO_TIFF_LOAD_HH