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