[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

impex.hxx
Go to the documentation of this file.
1 /************************************************************************/
2 /* */
3 /* Copyright 2001-2002 by Gunnar Kedenburg */
4 /* Copyright 2012 Christoph Spiel and Ullrich Koethe */
5 /* */
6 /* This file is part of the VIGRA computer vision library. */
7 /* The VIGRA Website is */
8 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
9 /* Please direct questions, bug reports, and contributions to */
10 /* ullrich.koethe@iwr.uni-heidelberg.de or */
11 /* vigra@informatik.uni-hamburg.de */
12 /* */
13 /* Permission is hereby granted, free of charge, to any person */
14 /* obtaining a copy of this software and associated documentation */
15 /* files (the "Software"), to deal in the Software without */
16 /* restriction, including without limitation the rights to use, */
17 /* copy, modify, merge, publish, distribute, sublicense, and/or */
18 /* sell copies of the Software, and to permit persons to whom the */
19 /* Software is furnished to do so, subject to the following */
20 /* conditions: */
21 /* */
22 /* The above copyright notice and this permission notice shall be */
23 /* included in all copies or substantial portions of the */
24 /* Software. */
25 /* */
26 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
27 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
28 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
29 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
30 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
31 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
32 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
33 /* OTHER DEALINGS IN THE SOFTWARE. */
34 /* */
35 /************************************************************************/
36 
37 
38 /*!
39  * \file impex.hxx
40  * \brief image import and export functions
41  *
42  * This module implements functions importImage() and exportImage().
43  * The matching implementation for any given datatype is selected by
44  * template meta code.
45  *
46  */
47 
48 #ifndef VIGRA_IMPEX_HXX
49 #define VIGRA_IMPEX_HXX
50 
51 #include "stdimage.hxx"
52 #include "imageinfo.hxx"
53 #include "impexbase.hxx"
54 
55 namespace vigra
56 {
57 /** \addtogroup VigraImpex
58  * @{
59 */
60  namespace detail
61  {
62  template <class ValueType,
63  class ImageIterator, class ImageAccessor>
64  void
65  read_image_band(Decoder* decoder,
66  ImageIterator image_iterator, ImageAccessor image_accessor)
67  {
68  typedef typename ImageIterator::row_iterator ImageRowIterator;
69 
70  const unsigned width(decoder->getWidth());
71  const unsigned height(decoder->getHeight());
72  const unsigned offset(decoder->getOffset());
73 
74  for (unsigned y = 0U; y != height; ++y)
75  {
76  decoder->nextScanline();
77 
78  const ValueType* scanline = static_cast<const ValueType*>(decoder->currentScanlineOfBand(0));
79 
80  ImageRowIterator is(image_iterator.rowIterator());
81  const ImageRowIterator is_end(is + width);
82 
83  while (is != is_end)
84  {
85  image_accessor.set(*scanline, is);
86  scanline += offset;
87  ++is;
88  }
89 
90  ++image_iterator.y;
91  }
92  }
93 
94 
95  template <class ValueType,
96  class ImageIterator, class ImageAccessor>
97  void
98  read_image_bands(Decoder* decoder,
99  ImageIterator image_iterator, ImageAccessor image_accessor)
100  {
101  typedef typename ImageIterator::row_iterator ImageRowIterator;
102 
103  const unsigned width(decoder->getWidth());
104  const unsigned height(decoder->getHeight());
105  const unsigned offset(decoder->getOffset());
106  const unsigned accessor_size(image_accessor.size(image_iterator));
107 
108  // OPTIMIZATION: Specialization for the most common case
109  // of an RGB-image, i.e. 3 channels.
110  if (accessor_size == 3U)
111  {
112  const ValueType* scanline_0;
113  const ValueType* scanline_1;
114  const ValueType* scanline_2;
115 
116  for (unsigned y = 0U; y != height; ++y)
117  {
118  decoder->nextScanline();
119 
120  scanline_0 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(0));
121  scanline_1 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(1));
122  scanline_2 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(2));
123 
124  ImageRowIterator is(image_iterator.rowIterator());
125  const ImageRowIterator is_end(is + width);
126 
127  while (is != is_end)
128  {
129  image_accessor.setComponent(*scanline_0, is, 0);
130  image_accessor.setComponent(*scanline_1, is, 1);
131  image_accessor.setComponent(*scanline_2, is, 2);
132 
133  scanline_0 += offset;
134  scanline_1 += offset;
135  scanline_2 += offset;
136 
137  ++is;
138  }
139 
140  ++image_iterator.y;
141  }
142  }
143  else
144  {
145  std::vector<const ValueType*> scanlines(accessor_size);
146 
147  for (unsigned y = 0U; y != height; ++y)
148  {
149  decoder->nextScanline();
150 
151  for (unsigned i = 0U; i != accessor_size; ++i)
152  {
153  scanlines[i] = static_cast<const ValueType*>(decoder->currentScanlineOfBand(i));
154  }
155 
156  ImageRowIterator is(image_iterator.rowIterator());
157  const ImageRowIterator is_end(is + width);
158 
159  while (is != is_end)
160  {
161  for (unsigned i = 0U; i != accessor_size; ++i)
162  {
163  image_accessor.setComponent(*scanlines[i], is, static_cast<int>(i));
164  scanlines[i] += offset;
165  }
166  ++is;
167  }
168 
169  ++image_iterator.y;
170  }
171  }
172  }
173 
174 
175  template <class ImageIterator, class ImageAccessor>
176  void
177  importImage(const ImageImportInfo& import_info,
178  ImageIterator image_iterator, ImageAccessor image_accessor,
179  /* isScalar? */ VigraTrueType)
180  {
181  VIGRA_UNIQUE_PTR<Decoder> decoder(vigra::decoder(import_info));
182 
183  switch (pixel_t_of_string(decoder->getPixelType()))
184  {
185  case UNSIGNED_INT_8:
186  read_image_band<UInt8>(decoder.get(), image_iterator, image_accessor);
187  break;
188  case UNSIGNED_INT_16:
189  read_image_band<UInt16>(decoder.get(), image_iterator, image_accessor);
190  break;
191  case UNSIGNED_INT_32:
192  read_image_band<UInt32>(decoder.get(), image_iterator, image_accessor);
193  break;
194  case SIGNED_INT_16:
195  read_image_band<Int16>(decoder.get(), image_iterator, image_accessor);
196  break;
197  case SIGNED_INT_32:
198  read_image_band<Int32>(decoder.get(), image_iterator, image_accessor);
199  break;
200  case IEEE_FLOAT_32:
201  read_image_band<float>(decoder.get(), image_iterator, image_accessor);
202  break;
203  case IEEE_FLOAT_64:
204  read_image_band<double>(decoder.get(), image_iterator, image_accessor);
205  break;
206  default:
207  vigra_fail("detail::importImage<scalar>: not reached");
208  }
209 
210  decoder->close();
211  }
212 
213 
214  template <class ImageIterator, class ImageAccessor>
215  void
216  importImage(const ImageImportInfo& import_info,
217  ImageIterator image_iterator, ImageAccessor image_accessor,
218  /* isScalar? */ VigraFalseType)
219  {
220  VIGRA_UNIQUE_PTR<Decoder> decoder(vigra::decoder(import_info));
221 
222  switch (pixel_t_of_string(decoder->getPixelType()))
223  {
224  case UNSIGNED_INT_8:
225  read_image_bands<UInt8>(decoder.get(), image_iterator, image_accessor);
226  break;
227  case UNSIGNED_INT_16:
228  read_image_bands<UInt16>(decoder.get(), image_iterator, image_accessor);
229  break;
230  case UNSIGNED_INT_32:
231  read_image_bands<UInt32>(decoder.get(), image_iterator, image_accessor);
232  break;
233  case SIGNED_INT_16:
234  read_image_bands<Int16>(decoder.get(), image_iterator, image_accessor);
235  break;
236  case SIGNED_INT_32:
237  read_image_bands<Int32>(decoder.get(), image_iterator, image_accessor);
238  break;
239  case IEEE_FLOAT_32:
240  read_image_bands<float>(decoder.get(), image_iterator, image_accessor);
241  break;
242  case IEEE_FLOAT_64:
243  read_image_bands<double>(decoder.get(), image_iterator, image_accessor);
244  break;
245  default:
246  vigra_fail("vigra::detail::importImage<non-scalar>: not reached");
247  }
248 
249  decoder->close();
250  }
251 
252  template<class ValueType,
253  class ImageIterator, class ImageAccessor, class ImageScaler>
254  void
255  write_image_band(Encoder* encoder,
256  ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
257  const ImageScaler& image_scaler)
258  {
259  typedef typename ImageIterator::row_iterator ImageRowIterator;
260  typedef typename ImageAccessor::value_type ImageValueType;
261 
262  typedef RequiresExplicitCast<ValueType> explicit_cast;
263 
264  vigra_precondition(image_lower_right.x >= image_upper_left.x,
265  "vigra::detail::write_image_band: negative width");
266  vigra_precondition(image_lower_right.y >= image_upper_left.y,
267  "vigra::detail::write_image_band: negative height");
268 
269  const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x));
270  const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y));
271 
272  encoder->setWidth(width);
273  encoder->setHeight(height);
274  encoder->setNumBands(1);
275  encoder->finalizeSettings();
276 
277  const unsigned offset(encoder->getOffset()); // correct offset only _after_ finalizeSettings()
278 
279  // IMPLEMENTATION NOTE: We avoid calling the default
280  // constructor to allow classes ImageIterator that do not
281  // define one.
282  ImageIterator image_iterator(image_upper_left);
283 
284  for (unsigned y = 0U; y != height; ++y)
285  {
286  ValueType* scanline = static_cast<ValueType*>(encoder->currentScanlineOfBand(0));
287 
288  ImageRowIterator is(image_iterator.rowIterator());
289  const ImageRowIterator is_end(is + width);
290 
291  while (is != is_end)
292  {
293  *scanline = explicit_cast::cast(image_scaler(image_accessor(is)));
294  scanline += offset;
295  ++is;
296  }
297 
298  encoder->nextScanline();
299 
300  ++image_iterator.y;
301  }
302  }
303 
304 
305  template<class ValueType,
306  class ImageIterator, class ImageAccessor, class ImageScaler>
307  void
308  write_image_bands(Encoder* encoder,
309  ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
310  const ImageScaler& image_scaler)
311  {
312  typedef typename ImageIterator::row_iterator ImageRowIterator;
313  typedef RequiresExplicitCast<ValueType> explicit_cast;
314 
315  vigra_precondition(image_lower_right.x >= image_upper_left.x,
316  "vigra::detail::write_image_bands: negative width");
317  vigra_precondition(image_lower_right.y >= image_upper_left.y,
318  "vigra::detail::write_image_bands: negative height");
319 
320  const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x));
321  const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y));
322  const unsigned accessor_size(image_accessor.size(image_upper_left));
323 
324  encoder->setWidth(width);
325  encoder->setHeight(height);
326  encoder->setNumBands(accessor_size);
327  encoder->finalizeSettings();
328 
329  const unsigned offset(encoder->getOffset()); // correct offset only _after_ finalizeSettings()
330 
331  // IMPLEMENTATION NOTE: We avoid calling the default
332  // constructor to allow classes ImageIterator that do not
333  // define one.
334  ImageIterator image_iterator(image_upper_left);
335 
336  // OPTIMIZATION: Specialization for the most common case
337  // of an RGB-image, i.e. 3 channels.
338  if (accessor_size == 3U)
339  {
340  ValueType* scanline_0;
341  ValueType* scanline_1;
342  ValueType* scanline_2;
343 
344  for (unsigned y = 0U; y != height; ++y)
345  {
346  scanline_0 = static_cast<ValueType*>(encoder->currentScanlineOfBand(0));
347  scanline_1 = static_cast<ValueType*>(encoder->currentScanlineOfBand(1));
348  scanline_2 = static_cast<ValueType*>(encoder->currentScanlineOfBand(2));
349 
350  ImageRowIterator is(image_iterator.rowIterator());
351  const ImageRowIterator is_end(is + width);
352 
353  while (is != is_end)
354  {
355  *scanline_0 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 0)));
356  *scanline_1 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 1)));
357  *scanline_2 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 2)));
358 
359  scanline_0 += offset;
360  scanline_1 += offset;
361  scanline_2 += offset;
362 
363  ++is;
364  }
365 
366  encoder->nextScanline();
367 
368  ++image_iterator.y;
369  }
370  }
371  else
372  {
373  std::vector<ValueType*> scanlines(accessor_size);
374 
375  for (unsigned y = 0U; y != height; ++y)
376  {
377  for (unsigned i = 0U; i != accessor_size; ++i)
378  {
379  scanlines[i] = static_cast<ValueType*>(encoder->currentScanlineOfBand(i));
380  }
381 
382  ImageRowIterator is(image_iterator.rowIterator());
383  const ImageRowIterator is_end(is + width);
384 
385  while (is != is_end)
386  {
387  for (unsigned i = 0U; i != accessor_size; ++i)
388  {
389  *scanlines[i] = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, static_cast<int>(i))));
390  scanlines[i] += offset;
391  }
392  ++is;
393  }
394 
395  encoder->nextScanline();
396 
397  ++image_iterator.y;
398  }
399  }
400  }
401 
402 
403  template <class ImageIterator, class ImageAccessor>
404  void
405  exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
406  const ImageExportInfo& export_info,
407  /* isScalar? */ VigraTrueType)
408  {
409  typedef typename ImageAccessor::value_type ImageValueType;
410 
411  VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info));
412 
413  std::string pixel_type(export_info.getPixelType());
414  const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type));
415  const pixel_t type(pixel_t_of_string(pixel_type));
416 
417  encoder->setPixelType(pixel_type);
418 
419  const range_t image_source_range(find_source_value_range(export_info,
420  image_upper_left, image_lower_right, image_accessor));
421  const range_t destination_range(find_destination_value_range(export_info, type));
422 
423  if ((downcast || export_info.hasForcedRangeMapping()) &&
424  (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second))
425  {
426  const linear_transform image_rescaler(image_source_range, destination_range);
427 
428  switch (type)
429  {
430  case UNSIGNED_INT_8:
431  write_image_band<UInt8>(encoder.get(),
432  image_upper_left, image_lower_right, image_accessor, image_rescaler);
433  break;
434  case UNSIGNED_INT_16:
435  write_image_band<UInt16>(encoder.get(),
436  image_upper_left, image_lower_right, image_accessor, image_rescaler);
437  break;
438  case UNSIGNED_INT_32:
439  write_image_band<UInt32>(encoder.get(),
440  image_upper_left, image_lower_right, image_accessor, image_rescaler);
441  break;
442  case SIGNED_INT_16:
443  write_image_band<Int16>(encoder.get(),
444  image_upper_left, image_lower_right, image_accessor, image_rescaler);
445  break;
446  case SIGNED_INT_32:
447  write_image_band<Int32>(encoder.get(),
448  image_upper_left, image_lower_right, image_accessor, image_rescaler);
449  break;
450  case IEEE_FLOAT_32:
451  write_image_band<float>(encoder.get(),
452  image_upper_left, image_lower_right, image_accessor, image_rescaler);
453  break;
454  case IEEE_FLOAT_64:
455  write_image_band<double>(encoder.get(),
456  image_upper_left, image_lower_right, image_accessor, image_rescaler);
457  break;
458  default:
459  vigra_fail("vigra::detail::exportImage<scalar>: not reached");
460  }
461  }
462  else
463  {
464  switch (type)
465  {
466  case UNSIGNED_INT_8:
467  write_image_band<UInt8>(encoder.get(),
468  image_upper_left, image_lower_right, image_accessor, identity());
469  break;
470  case UNSIGNED_INT_16:
471  write_image_band<UInt16>(encoder.get(),
472  image_upper_left, image_lower_right, image_accessor, identity());
473  break;
474  case UNSIGNED_INT_32:
475  write_image_band<UInt32>(encoder.get(),
476  image_upper_left, image_lower_right, image_accessor, identity());
477  break;
478  case SIGNED_INT_16:
479  write_image_band<Int16>(encoder.get(),
480  image_upper_left, image_lower_right, image_accessor, identity());
481  break;
482  case SIGNED_INT_32:
483  write_image_band<Int32>(encoder.get(),
484  image_upper_left, image_lower_right, image_accessor, identity());
485  break;
486  case IEEE_FLOAT_32:
487  write_image_band<float>(encoder.get(),
488  image_upper_left, image_lower_right, image_accessor, identity());
489  break;
490  case IEEE_FLOAT_64:
491  write_image_band<double>(encoder.get(),
492  image_upper_left, image_lower_right, image_accessor, identity());
493  break;
494  default:
495  vigra_fail("vigra::detail::exportImage<scalar>: not reached");
496  }
497  }
498 
499  encoder->close();
500  }
501 
502 
503  template <class ImageIterator, class ImageAccessor>
504  void
505  exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
506  const ImageExportInfo& export_info,
507  /* isScalar? */ VigraFalseType)
508  {
509  typedef typename ImageAccessor::value_type ImageBaseType;
510  typedef typename ImageBaseType::value_type ImageValueType;
511 
512  VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info));
513 
514  std::string pixel_type(export_info.getPixelType());
515  const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type));
516  const pixel_t type(pixel_t_of_string(pixel_type));
517 
518  encoder->setPixelType(pixel_type);
519 
520  vigra_precondition(isBandNumberSupported(encoder->getFileType(), image_accessor.size(image_upper_left)),
521  "exportImage(): file format does not support requested number of bands (color channels)");
522 
523  const range_t image_source_range(find_source_value_range(export_info,
524  image_upper_left, image_lower_right, image_accessor));
525  const range_t destination_range(find_destination_value_range(export_info, pixel_t_of_string(pixel_type)));
526 
527  if ((downcast || export_info.hasForcedRangeMapping()) &&
528  (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second))
529  {
530  const linear_transform image_rescaler(image_source_range, destination_range);
531 
532  switch (type)
533  {
534  case UNSIGNED_INT_8:
535  write_image_bands<UInt8>(encoder.get(),
536  image_upper_left, image_lower_right, image_accessor, image_rescaler);
537  break;
538  case UNSIGNED_INT_16:
539  write_image_bands<UInt16>(encoder.get(),
540  image_upper_left, image_lower_right, image_accessor, image_rescaler);
541  break;
542  case UNSIGNED_INT_32:
543  write_image_bands<UInt32>(encoder.get(),
544  image_upper_left, image_lower_right, image_accessor, image_rescaler);
545  break;
546  case SIGNED_INT_16:
547  write_image_bands<Int16>(encoder.get(),
548  image_upper_left, image_lower_right, image_accessor, image_rescaler);
549  break;
550  case SIGNED_INT_32:
551  write_image_bands<Int32>(encoder.get(),
552  image_upper_left, image_lower_right, image_accessor, image_rescaler);
553  break;
554  case IEEE_FLOAT_32:
555  write_image_bands<float>(encoder.get(),
556  image_upper_left, image_lower_right, image_accessor, image_rescaler);
557  break;
558  case IEEE_FLOAT_64:
559  write_image_bands<double>(encoder.get(),
560  image_upper_left, image_lower_right, image_accessor, image_rescaler);
561  break;
562  default:
563  vigra_fail("vigra::detail::exportImage<non-scalar>: not reached");
564  }
565  }
566  else
567  {
568  switch (type)
569  {
570  case UNSIGNED_INT_8:
571  write_image_bands<UInt8>(encoder.get(),
572  image_upper_left, image_lower_right, image_accessor, identity());
573  break;
574  case UNSIGNED_INT_16:
575  write_image_bands<UInt16>(encoder.get(),
576  image_upper_left, image_lower_right, image_accessor, identity());
577  break;
578  case UNSIGNED_INT_32:
579  write_image_bands<UInt32>(encoder.get(),
580  image_upper_left, image_lower_right, image_accessor, identity());
581  break;
582  case SIGNED_INT_16:
583  write_image_bands<Int16>(encoder.get(),
584  image_upper_left, image_lower_right, image_accessor, identity());
585  break;
586  case SIGNED_INT_32:
587  write_image_bands<Int32>(encoder.get(),
588  image_upper_left, image_lower_right, image_accessor, identity());
589  break;
590  case IEEE_FLOAT_32:
591  write_image_bands<float>(encoder.get(),
592  image_upper_left, image_lower_right, image_accessor, identity());
593  break;
594  case IEEE_FLOAT_64:
595  write_image_bands<double>(encoder.get(),
596  image_upper_left, image_lower_right, image_accessor, identity());
597  break;
598  default:
599  vigra_fail("vigra::detail::exportImage<non-scalar>: not reached");
600  }
601  }
602 
603  encoder->close();
604  }
605  } // end namespace detail
606 
607  /*!
608  * \brief Read the image specified by the given \ref
609  * vigra::ImageImportInfo object.
610  *
611  * <B>Declarations</B>
612  *
613  * Pass arguments explicitly:
614  * \code
615  * namespace vigra {
616  * template <class ImageIterator, class Accessor>
617  * void
618  * importImage(const ImageImportInfo& importInfo,
619  * ImageIterator imageIterator, Accessor imageAccessor)
620  * }
621  * \endcode
622  *
623  * Use argument objects in conjunction with \ref ArgumentObjectFactories :
624  * \code
625  * namespace vigra {
626  * template <class ImageIterator, class Accessor>
627  * inline void
628  * importImage(const ImageImportInfo& importInfo,
629  * const pair<ImageIterator, Accessor>& image)
630  * }
631  * \endcode
632  *
633  * <B>Usage</B>
634  *
635  * <B>\#include <vigra/impex.hxx></B>
636  *
637  * Namespace: vigra
638  *
639  * \code
640  * ImageImportInfo info("myimage.gif");
641  *
642  * if (info.isGrayscale())
643  * {
644  * // create byte image of appropriate size
645  * BImage image(info.width(), info.height());
646  *
647  * importImage(info, destImage(image));
648  * ...
649  * }
650  * else
651  * {
652  * // create byte RGB image of appropriate size
653  * BRGBImage image(info.width(), info.height());
654  *
655  * importImage(info, destImage(image));
656  * ...
657  * }
658  * \endcode
659  *
660  * <B>Preconditions</B>
661  *
662  * - The image file must be readable and
663  * - the file type must be one of the following:
664  *
665  * | Type | Extension | Name | Support Library |
666  * |------|-----------|------------------------------------------------------------|-----------------|
667  * | BMP | bmp | Microsoft Windows bitmap image file | |
668  * | EXR | exr | OpenEXR high dynamic range image format | libopenexr |
669  * | GIF | gif | CompuServe graphics interchange format, 8-bit color | |
670  * | HDR | hdr | Radiance RGBE high dynamic range image format | libexr? |
671  * | JPEG | jpg, jpeg | Joint Photographic Experts Group JFIF format, 24-bit color | libjpeg |
672  * | PBM | pbm | Portable bitmap format (black and white) | |
673  * | PGM | pgm | Portable graymap format (gray scale) | |
674  * | PNG | png | Portable Network Graphic | libpng |
675  * | PNM | pnm | Portable anymap | |
676  * | PPM | ppm | Portable pixmap format (color) | |
677  * | SUN | ras | SUN Rasterfile | |
678  * | TIFF | tif, tiff | Tagged Image File Format | libtiff |
679  * | VIFF | xv | Khoros Visualization image file | |
680  */
681  doxygen_overloaded_function(template <...> inline void importImage)
682 
683 
684  template <class ImageIterator, class ImageAccessor>
685  inline void
686  importImage(const ImageImportInfo& import_info,
687  ImageIterator image_iterator, ImageAccessor image_accessor)
688  {
689  typedef typename ImageAccessor::value_type ImageValueType;
690  typedef typename NumericTraits<ImageValueType>::isScalar is_scalar;
691 
692  detail::importImage(import_info,
693  image_iterator, image_accessor,
694  is_scalar());
695  }
696 
697 
698  template <class ImageIterator, class ImageAccessor>
699  inline void
700  importImage(const ImageImportInfo& import_info,
701  const vigra::pair<ImageIterator, ImageAccessor>& image)
702  {
703  importImage(import_info,
704  image.first, image.second);
705  }
706 
707  /*!
708  * \brief Write an image given a \ref vigra::ImageExportInfo object.
709  *
710  * If the file format to be exported to supports the pixel type of
711  * the source image, the pixel type will be kept
712  * (e.g. <tt>float</tt> can be stored as TIFF without conversion,
713  * in contrast to most other image export toolkits). Otherwise,
714  * the pixel values are transformed to the range 0..255 and
715  * converted to <tt>unsigned char</tt>. Currently, the following
716  * file formats are supported. The pixel types given in brackets
717  * are those that are written without conversion:
718  * - BMP: Microsoft Windows bitmap image file (pixel types: UINT8 as gray and RGB);
719  * - GIF: CompuServe graphics interchange format, 8-bit color (pixel types: UINT8 as gray and RGB);
720  * - JPEG: Joint Photographic Experts Group JFIF format, compressed 24-bit color
721  * (pixel types: UINT8 as gray and RGB), only available if libjpeg is installed;
722  * - PNG: Portable Network Graphic (pixel types: UINT8 and UINT16 with up to 4 channels),
723  * only available if libpng is installed;
724  * - PBM: Portable bitmap format (black and white);
725  * - PGM: Portable graymap format (pixel types: UINT8, INT16, INT32 as gray scale);
726  * - PNM: Portable anymap (pixel types: UINT8, INT16, INT32 as gray and RGB);
727  * - PPM: Portable pixmap format (pixel types: UINT8, INT16, INT32 as RGB);
728  * - SUN: SUN Rasterfile (pixel types: UINT8 as gray and RGB);
729  * - TIFF: Tagged Image File Format
730  * (pixel types: UINT8, INT16, INT32, FLOAT, DOUBLE with up to 4 channels),
731  * only available if libtiff is installed;
732  * - VIFF: Khoros Visualization image file
733  * (pixel types: UINT8, INT16, INT32, FLOAT, DOUBLE with arbitrary many channels);
734  *
735  * <B>Declarations</B>
736  *
737  * Pass arguments explicitly:
738  * \code
739  * namespace vigra {
740  * template <class ImageIterator, class ImageAccessor>
741  * void
742  * exportImage(ImageIterator imageUpperLeft, ImageIterator imageLowerRight, ImageAccessor imageAccessor,
743  * const ImageExportInfo& exportInfo)
744  * }
745  * \endcode
746  *
747  * Use argument objects in conjunction with \ref ArgumentObjectFactories :
748  * \code
749  * namespace vigra {
750  * template <class ImageIterator, class ImageAccessor>
751  * void exportImage(ImageIterator imageUpperLeft, ImageIterator imageLowerRight, ImageAccessor imageAccessor,
752  * const ImageExportInfo& exportInfo)
753  * }
754  * \endcode
755  *
756  * <B>Usage</B>
757  *
758  * <B>\#include <vigra/impex.hxx></B>
759  *
760  * Namespace: vigra
761  * \code
762  * BRGBImage image(width, height);
763  * ...
764  *
765  * // write as JPEG image, using compression quality 80
766  * exportImage(srcImageRange(image),
767  * ImageExportInfo("my-image.jpg").setCompression("80"));
768  *
769  * // Force it to a particular pixel type. The pixel type must be supported by the
770  * // desired image file format, otherwise an \ref vigra::PreconditionViolation
771  * // exception will be thrown.
772  * exportImage(srcImageRange(image),
773  * ImageExportInfo("my-INT16-image.tif").setPixelType("INT16"));
774  * \endcode
775  *
776  * <B>Preconditions</B>
777  *
778  * - The image file must be writable and
779  * - the file type must be one of the supported file types.
780  */
781  doxygen_overloaded_function(template <...> inline void exportImage)
782 
783 
784  template <class ImageIterator, class ImageAccessor>
785  inline void
786  exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
787  const ImageExportInfo& export_info)
788  {
789  typedef typename ImageAccessor::value_type ImageValueType;
790  typedef typename NumericTraits<ImageValueType>::isScalar is_scalar;
791 
792  try
793  {
794  detail::exportImage(image_upper_left, image_lower_right, image_accessor,
795  export_info,
796  is_scalar());
797  }
798  catch (Encoder::TIFFCompressionException&)
799  {
800  ImageExportInfo info(export_info);
801 
802  info.setCompression("");
803  detail::exportImage(image_upper_left, image_lower_right, image_accessor,
804  info,
805  is_scalar());
806  }
807  }
808 
809 
810  template <class ImageIterator, class ImageAccessor>
811  inline void
812  exportImage(const vigra::triple<ImageIterator, ImageIterator, ImageAccessor>& image,
813  const ImageExportInfo& export_info)
814  {
815  exportImage(image.first, image.second, image.third,
816  export_info);
817  }
818 
819 /** @} */
820 
821 } // end namespace vigra
822 
823 #endif // VIGRA_IMPEX_HXX

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.9.0 (Tue Oct 22 2013)