Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 00025 00026 #ifndef MLN_IO_TIFF_LOAD_HH 00027 # define MLN_IO_TIFF_LOAD_HH 00028 00029 00037 00038 00039 # include <iostream> 00040 # include <fstream> 00041 # include <tiffio.h> 00042 00043 # include <mln/core/concept/image.hh> 00044 # include <mln/value/rgb8.hh> 00045 00046 00047 00048 namespace mln 00049 { 00050 00051 namespace io 00052 { 00053 00054 namespace tiff 00055 { 00056 00057 00059 // 00060 template <typename I> 00061 void load(Image<I>& ima_, const std::string& filename); 00062 00063 00064 00065 # ifndef MLN_INCLUDE_ONLY 00066 00067 00068 namespace internal 00069 { 00070 00071 inline 00072 point2d ij2rc_1(int i, int j, int ni_1, int nj_1) 00073 { 00074 (void) nj_1; 00075 return point2d(ni_1 - i, j); 00076 } 00077 00078 inline 00079 point2d ij2rc_2(int i, int j, int ni_1, int nj_1) 00080 { 00081 return point2d(ni_1 - i, nj_1 - j); 00082 } 00083 00084 inline 00085 point2d ij2rc_3(int i, int j, int ni_1, int nj_1) 00086 { 00087 (void) ni_1; 00088 return point2d(i, nj_1 - j); 00089 } 00090 00091 inline 00092 point2d ij2rc_4(int i, int j, int ni_1, int nj_1) 00093 { 00094 (void) ni_1; 00095 (void) nj_1; 00096 return point2d(i, j); 00097 } 00098 00099 inline 00100 point2d ij2rc_5(int i, int j, int ni_1, int nj_1) 00101 { 00102 (void) nj_1; 00103 return point2d(j, ni_1 - i); 00104 } 00105 00106 inline 00107 point2d ij2rc_6(int i, int j, int ni_1, int nj_1) 00108 { 00109 return point2d(nj_1 - j, ni_1 - i); 00110 } 00111 00112 inline 00113 point2d ij2rc_7(int i, int j, int ni_1, int nj_1) 00114 { 00115 (void) ni_1; 00116 return point2d(nj_1 - j, i); 00117 } 00118 00119 inline 00120 point2d ij2rc_8(int i, int j, int ni_1, int nj_1) 00121 { 00122 (void) ni_1; 00123 (void) nj_1; 00124 return point2d(j, i); 00125 } 00126 00127 00128 00129 template <typename I> 00130 inline 00131 I load_header(TIFF *file) 00132 { 00133 uint32 width, height; 00134 00135 TIFFGetField(file, TIFFTAG_IMAGEWIDTH, &width); 00136 TIFFGetField(file, TIFFTAG_IMAGELENGTH, &height); 00137 00138 mln_concrete(I) new_ima(height, width, 0); 00139 00140 return new_ima; 00141 } 00142 00143 00144 template <typename I> 00145 inline 00146 void load_data_rgb8(I& ima, TIFF *file) 00147 { 00148 uint16 bits_per_sample, samples_per_pixel; 00149 00150 TIFFGetField(file, TIFFTAG_BITSPERSAMPLE, &bits_per_sample); 00151 TIFFGetField(file, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel); 00152 00153 uint16 data_size = bits_per_sample * samples_per_pixel; 00154 if (data_size != 24 && data_size != 32) 00155 { 00156 std::cout << "Trying to load a non color TIFF " 00157 << "image into a color Milena image." << std::endl; 00158 abort(); 00159 } 00160 00161 uint32 npixels = ima.ncols() * ima.nrows(); 00162 uint32 *raster = (uint32 *) _TIFFmalloc(npixels * sizeof (uint32)); 00163 00164 if (!TIFFReadRGBAImage(file, ima.ncols(), ima.nrows(), raster, 0)) 00165 { 00166 std::cout << "Error while reading the image file. Is it corrupted?" 00167 << std::endl; 00168 abort(); 00169 } 00170 00171 uint16 orientation; 00172 TIFFGetField(file, TIFFTAG_ORIENTATION, &orientation); 00173 00174 typedef point2d (*fun_t)(int, int, int, int); 00175 fun_t funs[] = { 0, ij2rc_1, ij2rc_2, ij2rc_3, ij2rc_4, 00176 ij2rc_5, ij2rc_6, ij2rc_7, ij2rc_8 }; 00177 fun_t fun = funs[orientation]; 00178 00179 int ni_1, nj_1; 00180 unsigned idx = 0; 00181 00182 if (orientation <= 4) 00183 { 00184 ni_1 = ima.nrows() - 1; 00185 nj_1 = ima.ncols() - 1; 00186 for (int i = 0; i <= ni_1; ++i) 00187 for (int j = 0; j <= nj_1; ++j) 00188 { 00189 value::rgb8 v; 00190 00191 v.red() = (unsigned char) TIFFGetR(raster[idx]); 00192 v.green() = (unsigned char) TIFFGetG(raster[idx]); 00193 v.blue() = (unsigned char) TIFFGetB(raster[idx]); 00194 ima((*fun)(i, j, ni_1, nj_1)) = v; 00195 00196 ++idx; 00197 } 00198 } 00199 else 00200 { 00201 nj_1 = ima.nrows() - 1; 00202 ni_1 = ima.ncols() - 1; 00203 for (int j = 0; j <= nj_1; ++j) 00204 for (int i = 0; i <= ni_1; ++i) 00205 { 00206 value::rgb8 v; 00207 00208 v.red() = (unsigned char) TIFFGetR(raster[idx]); 00209 v.green() = (unsigned char) TIFFGetG(raster[idx]); 00210 v.blue() = (unsigned char) TIFFGetB(raster[idx]); 00211 ima((*fun)(i, j, ni_1, nj_1)) = v; 00212 00213 ++idx; 00214 } 00215 } 00216 00217 _TIFFfree(raster); 00218 } 00219 00220 00221 00222 00223 template <typename I> 00224 inline 00225 void load_data_scalar(I& ima, TIFF *file) 00226 { 00227 uint16 samples_per_pixel; 00228 TIFFGetField(file, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel); 00229 if (samples_per_pixel != 1) 00230 { 00231 std::cout << "Trying to load a non grayscale TIFF " 00232 << "image into a grayscale Milena image." << std::endl; 00233 abort(); 00234 } 00235 00236 uint32 npixels = ima.ncols() * ima.nrows(); 00237 uint32 *raster = (uint32 *) _TIFFmalloc(npixels * sizeof (uint32)); 00238 00239 if (!TIFFReadRGBAImage(file, ima.ncols(), ima.nrows(), raster, 0)) 00240 { 00241 std::cout << "Error while reading the image file. Is it corrupted?" 00242 << std::endl; 00243 abort(); 00244 } 00245 00246 uint16 orientation; 00247 TIFFGetField(file, TIFFTAG_ORIENTATION, &orientation); 00248 00249 typedef point2d (*fun_t)(int, int, int, int); 00250 fun_t funs[] = { 0, ij2rc_1, ij2rc_2, ij2rc_3, ij2rc_4, 00251 ij2rc_5, ij2rc_6, ij2rc_7, ij2rc_8 }; 00252 fun_t fun = funs[orientation]; 00253 00254 int ni_1, nj_1; 00255 unsigned idx = 0; 00256 00257 if (orientation <= 4) 00258 { 00259 ni_1 = ima.nrows() - 1; 00260 nj_1 = ima.ncols() - 1; 00261 for (int i = 0; i <= ni_1; ++i) 00262 for (int j = 0; j <= nj_1; ++j) 00263 { 00264 ima((*fun)(i, j, ni_1, nj_1)) = (unsigned char) TIFFGetR(raster[idx++]); 00265 } 00266 } 00267 else 00268 { 00269 nj_1 = ima.nrows() - 1; 00270 ni_1 = ima.ncols() - 1; 00271 for (int j = 0; j <= nj_1; ++j) 00272 for (int i = 0; i <= ni_1; ++i) 00273 { 00274 ima((*fun)(i, j, ni_1, nj_1)) = (unsigned char) TIFFGetR(raster[idx++]); 00275 } 00276 } 00277 00278 _TIFFfree(raster); 00279 } 00280 00281 template <typename I> 00282 inline 00283 void 00284 load_data_dispatch(const value::rgb8&, I& ima, TIFF *file) 00285 { 00286 load_data_rgb8(ima, file); 00287 } 00288 00289 template <typename S, typename I> 00290 inline 00291 void 00292 load_data_dispatch(const value::Scalar<S>&, I& ima, TIFF *file) 00293 { 00294 load_data_scalar(ima, file); 00295 } 00296 00297 template <typename I> 00298 inline 00299 void 00300 load_data_dispatch(const bool&, I& ima, TIFF *file) 00301 { 00302 load_data_scalar(ima, file); 00303 } 00304 00305 00306 template <typename I> 00307 inline 00308 void 00309 load_data_dispatch(I& ima, TIFF *file) 00310 { 00311 load_data_dispatch(mln_value(I)(), exact(ima), file); 00312 } 00313 00314 00315 } // end of namespace mln::io::tiff::internal 00316 00317 00318 00319 // Facade 00320 00321 template <typename I> 00322 inline 00323 void load(Image<I>& ima_, const std::string& filename) 00324 { 00325 trace::entering("mln::io::tiff::load"); 00326 00327 I& ima = exact(ima_); 00328 00329 TIFF *file = TIFFOpen(filename.c_str(), "r"); 00330 if (file == 0) 00331 { 00332 std::cerr << "io::tiff::load - Error: cannot open file '" 00333 << filename << "'!" 00334 << std::endl; 00335 abort(); 00336 } 00337 00338 ima = internal::load_header<I>(file); 00339 internal::load_data_dispatch(ima, file); 00340 00341 mln_postcondition(ima.is_valid()); 00342 00343 (void) TIFFClose(file); 00344 trace::exiting("mln::io::tiff::load"); 00345 } 00346 00347 # endif // ! MLN_INCLUDE_ONLY 00348 00349 } // end of namespace mln::io::tiff 00350 00351 } // end of namespace mln::io 00352 00353 } // end of namespace mln 00354 00355 #endif // ! MLN_IO_TIFF_LOAD_HH