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

impex.hxx VIGRA

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 #include "multi_shape.hxx"
55 
56 namespace vigra
57 {
58 /** \addtogroup VigraImpex
59  * @{
60 */
61  namespace detail
62  {
63  template <class ValueType,
64  class ImageIterator, class ImageAccessor>
65  void
66  read_image_band(Decoder* decoder,
67  ImageIterator image_iterator, ImageAccessor image_accessor)
68  {
69  typedef typename ImageIterator::row_iterator ImageRowIterator;
70 
71  const unsigned width(decoder->getWidth());
72  const unsigned height(decoder->getHeight());
73  const unsigned offset(decoder->getOffset());
74 
75  for (unsigned y = 0U; y != height; ++y)
76  {
77  decoder->nextScanline();
78 
79  const ValueType* scanline = static_cast<const ValueType*>(decoder->currentScanlineOfBand(0));
80 
81  ImageRowIterator is(image_iterator.rowIterator());
82  const ImageRowIterator is_end(is + width);
83 
84  while (is != is_end)
85  {
86  image_accessor.set(*scanline, is);
87  scanline += offset;
88  ++is;
89  }
90 
91  ++image_iterator.y;
92  }
93  }
94 
95 
96  template <class ValueType,
97  class ImageIterator, class ImageAccessor>
98  void
99  read_image_bands(Decoder* decoder,
100  ImageIterator image_iterator, ImageAccessor image_accessor)
101  {
102  typedef typename ImageIterator::row_iterator ImageRowIterator;
103 
104  const unsigned width(decoder->getWidth());
105  const unsigned height(decoder->getHeight());
106  const unsigned bands(decoder->getNumBands());
107  const unsigned offset(decoder->getOffset());
108  const unsigned accessor_size(image_accessor.size(image_iterator));
109 
110  // OPTIMIZATION: Specialization for the most common case
111  // of an RGB-image, i.e. 3 channels.
112  if (accessor_size == 3U)
113  {
114  const ValueType* scanline_0;
115  const ValueType* scanline_1;
116  const ValueType* scanline_2;
117 
118  for (unsigned y = 0U; y != height; ++y)
119  {
120  decoder->nextScanline();
121 
122  scanline_0 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(0));
123 
124  if(bands == 1)
125  {
126  scanline_1 = scanline_0;
127  scanline_2 = scanline_0;
128  }
129  else
130  {
131  scanline_1 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(1));
132  scanline_2 = static_cast<const ValueType*>(decoder->currentScanlineOfBand(2));
133  }
134 
135  ImageRowIterator is(image_iterator.rowIterator());
136  const ImageRowIterator is_end(is + width);
137 
138  while (is != is_end)
139  {
140  image_accessor.setComponent(*scanline_0, is, 0);
141  image_accessor.setComponent(*scanline_1, is, 1);
142  image_accessor.setComponent(*scanline_2, is, 2);
143 
144  scanline_0 += offset;
145  scanline_1 += offset;
146  scanline_2 += offset;
147 
148  ++is;
149  }
150 
151  ++image_iterator.y;
152  }
153  }
154  else
155  {
156  std::vector<const ValueType*> scanlines(accessor_size);
157 
158  for (unsigned y = 0U; y != height; ++y)
159  {
160  decoder->nextScanline();
161 
162  scanlines[0] = static_cast<const ValueType*>(decoder->currentScanlineOfBand(0));
163 
164  if(bands == 1)
165  {
166  for (unsigned i = 1U; i != accessor_size; ++i)
167  {
168  scanlines[i] = scanlines[0];
169  }
170  }
171  else
172  {
173  for (unsigned i = 1U; i != accessor_size; ++i)
174  {
175  scanlines[i] = static_cast<const ValueType*>(decoder->currentScanlineOfBand(i));
176  }
177  }
178 
179  ImageRowIterator is(image_iterator.rowIterator());
180  const ImageRowIterator is_end(is + width);
181 
182  while (is != is_end)
183  {
184  for (unsigned i = 0U; i != accessor_size; ++i)
185  {
186  image_accessor.setComponent(*scanlines[i], is, static_cast<int>(i));
187  scanlines[i] += offset;
188  }
189  ++is;
190  }
191 
192  ++image_iterator.y;
193  }
194  }
195  }
196 
197 
198  template <class ImageIterator, class ImageAccessor>
199  void
200  importImage(const ImageImportInfo& import_info,
201  ImageIterator image_iterator, ImageAccessor image_accessor,
202  /* isScalar? */ VigraTrueType)
203  {
204  VIGRA_UNIQUE_PTR<Decoder> decoder(vigra::decoder(import_info));
205 
206  switch (pixel_t_of_string(decoder->getPixelType()))
207  {
208  case UNSIGNED_INT_8:
209  read_image_band<UInt8>(decoder.get(), image_iterator, image_accessor);
210  break;
211  case UNSIGNED_INT_16:
212  read_image_band<UInt16>(decoder.get(), image_iterator, image_accessor);
213  break;
214  case UNSIGNED_INT_32:
215  read_image_band<UInt32>(decoder.get(), image_iterator, image_accessor);
216  break;
217  case SIGNED_INT_16:
218  read_image_band<Int16>(decoder.get(), image_iterator, image_accessor);
219  break;
220  case SIGNED_INT_32:
221  read_image_band<Int32>(decoder.get(), image_iterator, image_accessor);
222  break;
223  case IEEE_FLOAT_32:
224  read_image_band<float>(decoder.get(), image_iterator, image_accessor);
225  break;
226  case IEEE_FLOAT_64:
227  read_image_band<double>(decoder.get(), image_iterator, image_accessor);
228  break;
229  default:
230  vigra_fail("detail::importImage<scalar>: not reached");
231  }
232 
233  decoder->close();
234  }
235 
236 
237  template <class ImageIterator, class ImageAccessor>
238  void
239  importImage(const ImageImportInfo& import_info,
240  ImageIterator image_iterator, ImageAccessor image_accessor,
241  /* isScalar? */ VigraFalseType)
242  {
243  vigra_precondition(import_info.numBands() == image_accessor.size(image_iterator) ||
244  import_info.numBands() == 1,
245  "importImage(): Number of channels in input and destination image don't match.");
246 
247  VIGRA_UNIQUE_PTR<Decoder> decoder(vigra::decoder(import_info));
248 
249  switch (pixel_t_of_string(decoder->getPixelType()))
250  {
251  case UNSIGNED_INT_8:
252  read_image_bands<UInt8>(decoder.get(), image_iterator, image_accessor);
253  break;
254  case UNSIGNED_INT_16:
255  read_image_bands<UInt16>(decoder.get(), image_iterator, image_accessor);
256  break;
257  case UNSIGNED_INT_32:
258  read_image_bands<UInt32>(decoder.get(), image_iterator, image_accessor);
259  break;
260  case SIGNED_INT_16:
261  read_image_bands<Int16>(decoder.get(), image_iterator, image_accessor);
262  break;
263  case SIGNED_INT_32:
264  read_image_bands<Int32>(decoder.get(), image_iterator, image_accessor);
265  break;
266  case IEEE_FLOAT_32:
267  read_image_bands<float>(decoder.get(), image_iterator, image_accessor);
268  break;
269  case IEEE_FLOAT_64:
270  read_image_bands<double>(decoder.get(), image_iterator, image_accessor);
271  break;
272  default:
273  vigra_fail("vigra::detail::importImage<non-scalar>: not reached");
274  }
275 
276  decoder->close();
277  }
278 
279  template<class ValueType,
280  class ImageIterator, class ImageAccessor, class ImageScaler>
281  void
282  write_image_band(Encoder* encoder,
283  ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
284  const ImageScaler& image_scaler)
285  {
286  typedef typename ImageIterator::row_iterator ImageRowIterator;
287 
288  typedef RequiresExplicitCast<ValueType> explicit_cast;
289 
290  vigra_precondition(image_lower_right.x >= image_upper_left.x,
291  "vigra::detail::write_image_band: negative width");
292  vigra_precondition(image_lower_right.y >= image_upper_left.y,
293  "vigra::detail::write_image_band: negative height");
294 
295  const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x));
296  const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y));
297 
298  encoder->setWidth(width);
299  encoder->setHeight(height);
300  encoder->setNumBands(1);
301  encoder->finalizeSettings();
302 
303  const unsigned offset(encoder->getOffset()); // correct offset only _after_ finalizeSettings()
304 
305  // IMPLEMENTATION NOTE: We avoid calling the default
306  // constructor to allow classes ImageIterator that do not
307  // define one.
308  ImageIterator image_iterator(image_upper_left);
309 
310  for (unsigned y = 0U; y != height; ++y)
311  {
312  ValueType* scanline = static_cast<ValueType*>(encoder->currentScanlineOfBand(0));
313 
314  ImageRowIterator is(image_iterator.rowIterator());
315  const ImageRowIterator is_end(is + width);
316 
317  while (is != is_end)
318  {
319  *scanline = explicit_cast::cast(image_scaler(image_accessor(is)));
320  scanline += offset;
321  ++is;
322  }
323 
324  encoder->nextScanline();
325 
326  ++image_iterator.y;
327  }
328  }
329 
330 
331  template<class ValueType,
332  class ImageIterator, class ImageAccessor, class ImageScaler>
333  void
334  write_image_bands(Encoder* encoder,
335  ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
336  const ImageScaler& image_scaler)
337  {
338  typedef typename ImageIterator::row_iterator ImageRowIterator;
339  typedef RequiresExplicitCast<ValueType> explicit_cast;
340 
341  vigra_precondition(image_lower_right.x >= image_upper_left.x,
342  "vigra::detail::write_image_bands: negative width");
343  vigra_precondition(image_lower_right.y >= image_upper_left.y,
344  "vigra::detail::write_image_bands: negative height");
345 
346  const unsigned width(static_cast<unsigned>(image_lower_right.x - image_upper_left.x));
347  const unsigned height(static_cast<unsigned>(image_lower_right.y - image_upper_left.y));
348  const unsigned accessor_size(image_accessor.size(image_upper_left));
349 
350  encoder->setWidth(width);
351  encoder->setHeight(height);
352  encoder->setNumBands(accessor_size);
353  encoder->finalizeSettings();
354 
355  const unsigned offset(encoder->getOffset()); // correct offset only _after_ finalizeSettings()
356 
357  // IMPLEMENTATION NOTE: We avoid calling the default
358  // constructor to allow classes ImageIterator that do not
359  // define one.
360  ImageIterator image_iterator(image_upper_left);
361 
362  // OPTIMIZATION: Specialization for the most common case
363  // of an RGB-image, i.e. 3 channels.
364  if (accessor_size == 3U)
365  {
366  ValueType* scanline_0;
367  ValueType* scanline_1;
368  ValueType* scanline_2;
369 
370  for (unsigned y = 0U; y != height; ++y)
371  {
372  scanline_0 = static_cast<ValueType*>(encoder->currentScanlineOfBand(0));
373  scanline_1 = static_cast<ValueType*>(encoder->currentScanlineOfBand(1));
374  scanline_2 = static_cast<ValueType*>(encoder->currentScanlineOfBand(2));
375 
376  ImageRowIterator is(image_iterator.rowIterator());
377  const ImageRowIterator is_end(is + width);
378 
379  while (is != is_end)
380  {
381  *scanline_0 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 0)));
382  *scanline_1 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 1)));
383  *scanline_2 = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, 2)));
384 
385  scanline_0 += offset;
386  scanline_1 += offset;
387  scanline_2 += offset;
388 
389  ++is;
390  }
391 
392  encoder->nextScanline();
393 
394  ++image_iterator.y;
395  }
396  }
397  else
398  {
399  std::vector<ValueType*> scanlines(accessor_size);
400 
401  for (unsigned y = 0U; y != height; ++y)
402  {
403  for (unsigned i = 0U; i != accessor_size; ++i)
404  {
405  scanlines[i] = static_cast<ValueType*>(encoder->currentScanlineOfBand(i));
406  }
407 
408  ImageRowIterator is(image_iterator.rowIterator());
409  const ImageRowIterator is_end(is + width);
410 
411  while (is != is_end)
412  {
413  for (unsigned i = 0U; i != accessor_size; ++i)
414  {
415  *scanlines[i] = explicit_cast::cast(image_scaler(image_accessor.getComponent(is, static_cast<int>(i))));
416  scanlines[i] += offset;
417  }
418  ++is;
419  }
420 
421  encoder->nextScanline();
422 
423  ++image_iterator.y;
424  }
425  }
426  }
427 
428 
429  template <class ImageIterator, class ImageAccessor>
430  void
431  exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
432  const ImageExportInfo& export_info,
433  /* isScalar? */ VigraTrueType)
434  {
435  typedef typename ImageAccessor::value_type ImageValueType;
436 
437  VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info));
438 
439  std::string pixel_type(export_info.getPixelType());
440  const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type));
441  const pixel_t type(pixel_t_of_string(pixel_type));
442 
443  encoder->setPixelType(pixel_type);
444 
445  const range_t image_source_range(find_source_value_range(export_info,
446  image_upper_left, image_lower_right, image_accessor));
447  const range_t destination_range(find_destination_value_range(export_info, type));
448 
449  if ((downcast || export_info.hasForcedRangeMapping()) &&
450  (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second))
451  {
452  const linear_transform image_rescaler(image_source_range, destination_range);
453 
454  switch (type)
455  {
456  case UNSIGNED_INT_8:
457  write_image_band<UInt8>(encoder.get(),
458  image_upper_left, image_lower_right, image_accessor, image_rescaler);
459  break;
460  case UNSIGNED_INT_16:
461  write_image_band<UInt16>(encoder.get(),
462  image_upper_left, image_lower_right, image_accessor, image_rescaler);
463  break;
464  case UNSIGNED_INT_32:
465  write_image_band<UInt32>(encoder.get(),
466  image_upper_left, image_lower_right, image_accessor, image_rescaler);
467  break;
468  case SIGNED_INT_16:
469  write_image_band<Int16>(encoder.get(),
470  image_upper_left, image_lower_right, image_accessor, image_rescaler);
471  break;
472  case SIGNED_INT_32:
473  write_image_band<Int32>(encoder.get(),
474  image_upper_left, image_lower_right, image_accessor, image_rescaler);
475  break;
476  case IEEE_FLOAT_32:
477  write_image_band<float>(encoder.get(),
478  image_upper_left, image_lower_right, image_accessor, image_rescaler);
479  break;
480  case IEEE_FLOAT_64:
481  write_image_band<double>(encoder.get(),
482  image_upper_left, image_lower_right, image_accessor, image_rescaler);
483  break;
484  default:
485  vigra_fail("vigra::detail::exportImage<scalar>: not reached");
486  }
487  }
488  else
489  {
490  switch (type)
491  {
492  case UNSIGNED_INT_8:
493  write_image_band<UInt8>(encoder.get(),
494  image_upper_left, image_lower_right, image_accessor, identity());
495  break;
496  case UNSIGNED_INT_16:
497  write_image_band<UInt16>(encoder.get(),
498  image_upper_left, image_lower_right, image_accessor, identity());
499  break;
500  case UNSIGNED_INT_32:
501  write_image_band<UInt32>(encoder.get(),
502  image_upper_left, image_lower_right, image_accessor, identity());
503  break;
504  case SIGNED_INT_16:
505  write_image_band<Int16>(encoder.get(),
506  image_upper_left, image_lower_right, image_accessor, identity());
507  break;
508  case SIGNED_INT_32:
509  write_image_band<Int32>(encoder.get(),
510  image_upper_left, image_lower_right, image_accessor, identity());
511  break;
512  case IEEE_FLOAT_32:
513  write_image_band<float>(encoder.get(),
514  image_upper_left, image_lower_right, image_accessor, identity());
515  break;
516  case IEEE_FLOAT_64:
517  write_image_band<double>(encoder.get(),
518  image_upper_left, image_lower_right, image_accessor, identity());
519  break;
520  default:
521  vigra_fail("vigra::detail::exportImage<scalar>: not reached");
522  }
523  }
524 
525  encoder->close();
526  }
527 
528 
529  template <class ImageIterator, class ImageAccessor>
530  void
531  exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
532  const ImageExportInfo& export_info,
533  /* isScalar? */ VigraFalseType)
534  {
535  typedef typename ImageAccessor::value_type ImageBaseType;
536  typedef typename ImageBaseType::value_type ImageValueType;
537 
538  VIGRA_UNIQUE_PTR<Encoder> encoder(vigra::encoder(export_info));
539 
540  std::string pixel_type(export_info.getPixelType());
541  const bool downcast(negotiatePixelType(encoder->getFileType(), TypeAsString<ImageValueType>::result(), pixel_type));
542  const pixel_t type(pixel_t_of_string(pixel_type));
543 
544  encoder->setPixelType(pixel_type);
545 
546  vigra_precondition(isBandNumberSupported(encoder->getFileType(), image_accessor.size(image_upper_left)),
547  "exportImage(): file format does not support requested number of bands (color channels)");
548 
549  const range_t image_source_range(find_source_value_range(export_info,
550  image_upper_left, image_lower_right, image_accessor));
551  const range_t destination_range(find_destination_value_range(export_info, pixel_t_of_string(pixel_type)));
552 
553  if ((downcast || export_info.hasForcedRangeMapping()) &&
554  (image_source_range.first != destination_range.first || image_source_range.second != destination_range.second))
555  {
556  const linear_transform image_rescaler(image_source_range, destination_range);
557 
558  switch (type)
559  {
560  case UNSIGNED_INT_8:
561  write_image_bands<UInt8>(encoder.get(),
562  image_upper_left, image_lower_right, image_accessor, image_rescaler);
563  break;
564  case UNSIGNED_INT_16:
565  write_image_bands<UInt16>(encoder.get(),
566  image_upper_left, image_lower_right, image_accessor, image_rescaler);
567  break;
568  case UNSIGNED_INT_32:
569  write_image_bands<UInt32>(encoder.get(),
570  image_upper_left, image_lower_right, image_accessor, image_rescaler);
571  break;
572  case SIGNED_INT_16:
573  write_image_bands<Int16>(encoder.get(),
574  image_upper_left, image_lower_right, image_accessor, image_rescaler);
575  break;
576  case SIGNED_INT_32:
577  write_image_bands<Int32>(encoder.get(),
578  image_upper_left, image_lower_right, image_accessor, image_rescaler);
579  break;
580  case IEEE_FLOAT_32:
581  write_image_bands<float>(encoder.get(),
582  image_upper_left, image_lower_right, image_accessor, image_rescaler);
583  break;
584  case IEEE_FLOAT_64:
585  write_image_bands<double>(encoder.get(),
586  image_upper_left, image_lower_right, image_accessor, image_rescaler);
587  break;
588  default:
589  vigra_fail("vigra::detail::exportImage<non-scalar>: not reached");
590  }
591  }
592  else
593  {
594  switch (type)
595  {
596  case UNSIGNED_INT_8:
597  write_image_bands<UInt8>(encoder.get(),
598  image_upper_left, image_lower_right, image_accessor, identity());
599  break;
600  case UNSIGNED_INT_16:
601  write_image_bands<UInt16>(encoder.get(),
602  image_upper_left, image_lower_right, image_accessor, identity());
603  break;
604  case UNSIGNED_INT_32:
605  write_image_bands<UInt32>(encoder.get(),
606  image_upper_left, image_lower_right, image_accessor, identity());
607  break;
608  case SIGNED_INT_16:
609  write_image_bands<Int16>(encoder.get(),
610  image_upper_left, image_lower_right, image_accessor, identity());
611  break;
612  case SIGNED_INT_32:
613  write_image_bands<Int32>(encoder.get(),
614  image_upper_left, image_lower_right, image_accessor, identity());
615  break;
616  case IEEE_FLOAT_32:
617  write_image_bands<float>(encoder.get(),
618  image_upper_left, image_lower_right, image_accessor, identity());
619  break;
620  case IEEE_FLOAT_64:
621  write_image_bands<double>(encoder.get(),
622  image_upper_left, image_lower_right, image_accessor, identity());
623  break;
624  default:
625  vigra_fail("vigra::detail::exportImage<non-scalar>: not reached");
626  }
627  }
628 
629  encoder->close();
630  }
631  } // end namespace detail
632 
633  /**
634  \brief Read an image from a file.
635 
636  If the first parameter is \ref vigra::ImageImportInfo, this function assumes that the destination
637  image has already the appropriate shape. If the first parameter is a string, the destination
638  must be a \ref vigra::MultiArray reference, which will be reshaped automatically.
639 
640  If the input image has only a single band, but the destination has multiple bands (e.g. is an RGB
641  image), all bands will receive the same data. When a multi-band file is read into a single-band
642  destination array, only the first band is read. Any other mismatch between the number of bands in
643  input and output is an error and will throw a precondition exception.
644 
645  <B>Declarations</B>
646 
647  pass 2D array views:
648  \code
649  namespace vigra {
650  // read the data into an array view of appropriate size
651  template <class T, class S>
652  void
653  importImage(ImageImportInfo const & import_info,
654  MultiArrayView<2, T, S> image);
655 
656  // resize the given array and then read the data
657  template <class T, class A>
658  void
659  importImage(char const * filename,
660  MultiArray<2, T, A> & image);
661 
662  template <class T, class A>
663  void
664  importImage(std::string const & filename,
665  MultiArray<2, T, A> & image);
666  }
667  \endcode
668 
669  \deprecatedAPI{importImage}
670  pass \ref ImageIterators and \ref DataAccessors :
671  \code
672  namespace vigra {
673  template <class ImageIterator, class Accessor>
674  void
675  importImage(const ImageImportInfo& importInfo,
676  ImageIterator imageIterator, Accessor imageAccessor)
677  }
678  \endcode
679  Use argument objects in conjunction with \ref ArgumentObjectFactories :
680  \code
681  namespace vigra {
682  template <class ImageIterator, class Accessor>
683  void
684  importImage(const ImageImportInfo& importInfo,
685  const pair<ImageIterator, Accessor>& image)
686  }
687  \endcode
688  \deprecatedEnd
689 
690  <b> Usage:</b>
691 
692  <B>\#include</B> <vigra/impex.hxx><br/>
693  Namespace: vigra
694 
695  \code
696  ImageImportInfo info("myimage.gif");
697 
698  if (info.isGrayscale())
699  {
700  // create byte image of appropriate size
701  MultiArray<2, unsigned char> image(info.width(), info.height());
702 
703  importImage(info, image);
704  ...
705  }
706  else
707  {
708  // create byte RGB image of appropriate size
709  MultiArray<2, RGBValue<unsigned char> > image(info.width(), info.height());
710 
711  importImage(info, image);
712  ...
713  }
714  \endcode
715  When the type of input image is already known, this can be shortened:
716  \code
717  // create empty float image
718  MultiArray<2, float> image;
719 
720  // resize image and read the data
721  importImage("myimage.png", image);
722  \endcode
723 
724  \deprecatedUsage{importImage}
725  \code
726  ImageImportInfo info("myimage.gif");
727 
728  if (info.isGrayscale())
729  {
730  // create byte image of appropriate size
731  BImage image(info.width(), info.height());
732 
733  importImage(info, destImage(image));
734  ...
735  }
736  else
737  {
738  // create byte RGB image of appropriate size
739  BRGBImage image(info.width(), info.height());
740 
741  importImage(info, destImage(image));
742  ...
743  }
744  \endcode
745  \deprecatedEnd
746 
747  <B>Preconditions</B>
748 
749  - The image file must be readable.
750  - The required support library must be installed (if the table doesn't specify an external library,
751  VIGRA supports the format natively).
752  - The file type must be one of the following:
753 
754  <table cellspacing="10">
755  <tr align="left">
756  <th>Type</th><th> Extension </th><th> Name </th><th> Support Library </th>
757  </tr><tr>
758  <td> BMP </td><td> bmp </td><td> Microsoft Windows bitmap image file </td><td> </td>
759  </tr><tr>
760  <td> EXR </td><td> exr </td><td> OpenEXR high dynamic range image format </td><td> libopenexr </td>
761  </tr><tr>
762  <td> GIF </td><td> gif </td><td> CompuServe graphics interchange format, 8-bit color </td><td> </td>
763  </tr><tr>
764  <td> HDR </td><td> hdr </td><td> Radiance RGBE high dynamic range image format </td><td> </td>
765  </tr><tr>
766  <td> JPEG </td><td> jpg, jpeg </td><td> Joint Photographic Experts Group JFIF format, 24-bit color </td><td> libjpeg </td>
767  </tr><tr>
768  <td> PBM </td><td> pbm </td><td> Portable bitmap format (black and white) </td><td> </td>
769  </tr><tr>
770  <td> PGM </td><td> pgm </td><td> Portable graymap format (gray scale) </td><td> </td>
771  </tr><tr>
772  <td> PNG </td><td> png </td><td> Portable Network Graphic </td><td> libpng </td>
773  </tr><tr>
774  <td> PNM </td><td> pnm </td><td> Portable anymap </td><td> </td>
775  </tr><tr>
776  <td> PPM </td><td> ppm </td><td> Portable pixmap format (color) </td><td> </td>
777  </tr><tr>
778  <td> SUN </td><td> ras </td><td> SUN Rasterfile </td><td> </td>
779  </tr><tr>
780  <td> TIFF </td><td> tif, tiff </td><td> Tagged Image File Format </td><td> libtiff </td>
781  </tr><tr>
782  <td> VIFF </td><td> xv </td><td> Khoros Visualization image file </td><td> </td>
783  </table>
784 */
785  doxygen_overloaded_function(template <...> void importImage)
786 
787 
788  template <class ImageIterator, class ImageAccessor>
789  inline void
790  importImage(const ImageImportInfo& import_info,
791  ImageIterator image_iterator, ImageAccessor image_accessor)
792  {
793  typedef typename ImageAccessor::value_type ImageValueType;
794  typedef typename NumericTraits<ImageValueType>::isScalar is_scalar;
795 
796  detail::importImage(import_info,
797  image_iterator, image_accessor,
798  is_scalar());
799  }
800 
801 
802  template <class ImageIterator, class ImageAccessor>
803  inline void
804  importImage(ImageImportInfo const & import_info,
805  pair<ImageIterator, ImageAccessor> image)
806  {
807  importImage(import_info,
808  image.first, image.second);
809  }
810 
811  template <class T, class S>
812  inline void
813  importImage(ImageImportInfo const & import_info,
814  MultiArrayView<2, T, S> image)
815  {
816  vigra_precondition(import_info.shape() == image.shape(),
817  "importImage(): shape mismatch between input and output.");
818  importImage(import_info, destImage(image));
819  }
820 
821  template <class T, class A>
822  inline void
823  importImage(char const * name,
824  MultiArray<2, T, A> & image)
825  {
826  ImageImportInfo info(name);
827  image.reshape(info.shape());
828  importImage(info, destImage(image));
829  }
830 
831  template <class T, class A>
832  inline void
833  importImage(std::string const & name,
834  MultiArray<2, T, A> & image)
835  {
836  importImage(name.c_str(), image);
837  }
838 
839  /** \brief Write an image to a file.
840 
841  The file can be specified either by a file name or by a \ref vigra::ImageExportInfo object.
842  In the latter case, you have much more control about how the file is written. By default,
843  the file format to be created is guessed from the filename extension. This can be
844  overridden by an explicit file type in the ImageExportInfo object. If the file format
845  supports compression (e.g. JPEG and TIFF), default compression parameters are used
846  which can be overridden by the ImageExportInfo object.
847 
848  If the file format to be created supports the pixel type of the source image, this
849  pixel type will be kept in the file (e.g. <tt>float</tt> can be stored by TIFF without
850  conversion) unless the ImageExportInfo object
851  explicitly requests a different storage type. If the array's pixel type is not supported by
852  the file format, the pixel values are transformed to the range 0..255 and
853  converted to <tt>unsigned char</tt>, unless another mapping is explicitly requested by
854  the ImageExportInfo object.
855 
856  Currently, the following file formats are supported. The pixel types given in brackets
857  are those that are written without conversion:
858  - BMP: Microsoft Windows bitmap image file (pixel types: UINT8 as gray and RGB);
859  - GIF: CompuServe graphics interchange format, 8-bit color (pixel types: UINT8 as gray and RGB);
860  - JPEG: Joint Photographic Experts Group JFIF format, compressed 24-bit color
861  (pixel types: UINT8 as gray and RGB), only available if libjpeg is installed;
862  - PNG: Portable Network Graphic (pixel types: UINT8 and UINT16 with up to 4 channels),
863  only available if libpng is installed;
864  - PBM: Portable bitmap format (black and white);
865  - PGM: Portable graymap format (pixel types: UINT8, INT16, INT32 as gray scale);
866  - PNM: Portable anymap (pixel types: UINT8, INT16, INT32 as gray and RGB);
867  - PPM: Portable pixmap format (pixel types: UINT8, INT16, INT32 as RGB);
868  - SUN: SUN Rasterfile (pixel types: UINT8 as gray and RGB);
869  - TIFF: Tagged Image File Format
870  (pixel types: UINT8, INT16, INT32, FLOAT, DOUBLE with up to 4 channels),
871  only available if libtiff is installed;
872  - VIFF: Khoros Visualization image file
873  (pixel types: UINT8, INT16, INT32, FLOAT, DOUBLE with arbitrary many channels);
874 
875  <B>Declarations</B>
876 
877  pass 2D array views:
878  \code
879  namespace vigra {
880  template <class T, class S>
881  void
882  exportImage(MultiArrayView<2, T, S> const & image,
883  ImageExportInfo const & export_info);
884 
885  template <class T, class S>
886  void
887  exportImage(MultiArrayView<2, T, S> const & image,
888  char const * filename);
889 
890  template <class T, class S>
891  void
892  exportImage(MultiArrayView<2, T, S> const & image,
893  std::string const & filename);
894  }
895  \endcode
896 
897  \deprecatedAPI{exportImage}
898  pass \ref ImageIterators and \ref DataAccessors :
899  \code
900  namespace vigra {
901  template <class ImageIterator, class ImageAccessor>
902  void
903  exportImage(ImageIterator imageUpperLeft, ImageIterator imageLowerRight, ImageAccessor imageAccessor,
904  const ImageExportInfo& exportInfo)
905  }
906  \endcode
907  Use argument objects in conjunction with \ref ArgumentObjectFactories :
908  \code
909  namespace vigra {
910  template <class ImageIterator, class ImageAccessor>
911  void exportImage(ImageIterator imageUpperLeft, ImageIterator imageLowerRight, ImageAccessor imageAccessor,
912  const ImageExportInfo& exportInfo)
913  }
914  \endcode
915  \deprecatedEnd
916 
917  <b> Usage:</b>
918 
919  <B>\#include</B> <vigra/impex.hxx><br/>
920  Namespace: vigra
921 
922  \code
923  MultiArray<2, RGBValue<unsigned char> > image(width, height);
924  ...
925 
926  // write as JPEG image, using compression quality 80
927  exportImage(image,
928  ImageExportInfo("my-image.jpg").setCompression("80"));
929 
930  // Force it to a particular pixel type. The pixel type must be supported by the
931  // desired image file format, otherwise an \ref vigra::PreconditionViolation
932  // exception will be thrown.
933  exportImage(image,
934  ImageExportInfo("my-INT16-image.tif").setPixelType("INT16"));
935  \endcode
936 
937  \deprecatedUsage{exportImage}
938  \code
939  BRGBImage image(width, height);
940  ...
941 
942  // write as JPEG image, using compression quality 80
943  exportImage(srcImageRange(image),
944  ImageExportInfo("my-image.jpg").setCompression("80"));
945 
946  // Force it to a particular pixel type. The pixel type must be supported by the
947  // desired image file format, otherwise an \ref vigra::PreconditionViolation
948  // exception will be thrown.
949  exportImage(srcImageRange(image),
950  ImageExportInfo("my-INT16-image.tif").setPixelType("INT16"));
951  \endcode
952  \deprecatedEnd
953 
954  <B>Preconditions</B>
955 
956  - The image file must be writable and
957  - the file type must be one of the supported file types.
958 */
959  doxygen_overloaded_function(template <...> void exportImage)
960 
961 
962  template <class ImageIterator, class ImageAccessor>
963  inline void
964  exportImage(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor,
965  const ImageExportInfo& export_info)
966  {
967  typedef typename ImageAccessor::value_type ImageValueType;
968  typedef typename NumericTraits<ImageValueType>::isScalar is_scalar;
969 
970  try
971  {
972  detail::exportImage(image_upper_left, image_lower_right, image_accessor,
973  export_info,
974  is_scalar());
975  }
976  catch (Encoder::TIFFCompressionException&)
977  {
978  ImageExportInfo info(export_info);
979 
980  info.setCompression("");
981  detail::exportImage(image_upper_left, image_lower_right, image_accessor,
982  info,
983  is_scalar());
984  }
985  }
986 
987  template <class ImageIterator, class ImageAccessor>
988  inline void
989  exportImage(triple<ImageIterator, ImageIterator, ImageAccessor> image,
990  ImageExportInfo const & export_info)
991  {
992  exportImage(image.first, image.second, image.third,
993  export_info);
994  }
995 
996  template <class T, class S>
997  inline void
998  exportImage(MultiArrayView<2, T, S> const & image,
999  ImageExportInfo const & export_info)
1000  {
1001  exportImage(srcImageRange(image), export_info);
1002  }
1003 
1004  template <class T, class S>
1005  inline void
1006  exportImage(MultiArrayView<2, T, S> const & image,
1007  char const * name)
1008  {
1009  ImageExportInfo export_info(name);
1010  exportImage(srcImageRange(image), export_info);
1011  }
1012 
1013  template <class T, class S>
1014  inline void
1015  exportImage(MultiArrayView<2, T, S> const & image,
1016  std::string const & name)
1017  {
1018  ImageExportInfo export_info(name.c_str());
1019  exportImage(srcImageRange(image), export_info);
1020  }
1021 
1022 /** @} */
1023 
1024 } // end namespace vigra
1025 
1026 #endif // VIGRA_IMPEX_HXX
RowIteratorSelector::res row_iterator
Definition: imageiterator.hxx:605
Definition: accessor.hxx:43

© 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.10.0