Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tiffUtils.h
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
26 #ifndef _TIFFUTILS_H
27 #define _TIFFUTILS_H
28 
29 #include <vigra/tiff.hxx>
30 #include <vigra/imageinfo.hxx>
31 #include <vigra/transformimage.hxx>
32 #include <vigra/functorexpression.hxx>
33 
35 #include <hugin_utils/utils.h>
36 
37 #include <tiffio.h>
38 
39 // add this to the vigra_ext namespace
40 namespace vigra_ext {
41 
42 
43 //***************************************************************************
44 //
45 // functions to write tiff files with a single alpha channel.
46 //
47 //***************************************************************************
48 
58 inline void createTiffDirectory(vigra::TiffImage * tiff, const std::string & pagename,
59  const std::string & documentname,
60  const std::string comp,
61  uint16_t page, uint16_t nImg,
62  vigra::Diff2D offset,
63  vigra::Size2D fullSize,
64  const vigra::ImageExportInfo::ICCProfile & icc)
65 {
66  const float dpi = 150;
67  // create a new directory for our image
68  // hopefully I didn't forget too much stuff..
69  // TIFF tag reference at http://www.awaresystems.be/imaging/tiff/tifftags.html
70 
71  // set page
72  // FIXME: Also only needed for multilayer images
73  if (nImg > 1) {
74  // create tiff directory for the new layers
75  // TIFFOpen already created the first one.
76  if (page > 1) {
77  TIFFCreateDirectory (tiff);
78  }
79  TIFFSetField (tiff, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
80  TIFFSetField (tiff, TIFFTAG_PAGENUMBER, (unsigned short)page, (unsigned short)nImg);
81  }
82  TIFFSetField (tiff, TIFFTAG_XRESOLUTION, (float) dpi);
83  TIFFSetField (tiff, TIFFTAG_YRESOLUTION, (float) dpi);
84  // offsets must allways be positive so correct them
85  DEBUG_ASSERT(offset.x >= 0);
86  DEBUG_ASSERT(offset.y >= 0);
87  TIFFSetField (tiff, TIFFTAG_XPOSITION, (float)(offset.x / dpi));
88  TIFFSetField (tiff, TIFFTAG_YPOSITION, (float)(offset.y / dpi));
89 
90  // TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH
91  // are set when an image has been cropped out of a larger image.
92  // They reflect the size of the original uncropped image.
93  // The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used
94  // to determine the position of the smaller image in the larger one.
95  TIFFSetField(tiff, TIFFTAG_PIXAR_IMAGEFULLWIDTH, fullSize.x);
96  TIFFSetField(tiff, TIFFTAG_PIXAR_IMAGEFULLLENGTH, fullSize.y);
97 
98  // save input name.
99  TIFFSetField (tiff, TIFFTAG_DOCUMENTNAME, documentname.c_str());
100  TIFFSetField (tiff, TIFFTAG_PAGENAME, pagename.c_str() );
101  //
102  TIFFSetField (tiff, TIFFTAG_IMAGEDESCRIPTION, "stitched with hugin");
103 
104  // set compression
105  unsigned short tiffcomp;
106  if ( comp == "JPEG" )
107  tiffcomp = COMPRESSION_OJPEG;
108  else if ( comp == "LZW" )
109  tiffcomp = COMPRESSION_LZW;
110  else if ( comp == "DEFLATE" )
111  tiffcomp = COMPRESSION_DEFLATE;
112  else if ( comp == "PACKBITS" )
113  tiffcomp = COMPRESSION_PACKBITS;
114  else
115  tiffcomp = COMPRESSION_NONE;
116 
117  TIFFSetField(tiff, TIFFTAG_COMPRESSION, tiffcomp);
118 
119  // Set ICC profile, if available.
120  if (!icc.empty())
121  {
122  TIFFSetField(tiff, TIFFTAG_ICCPROFILE, icc.size(), icc.begin());
123  }
124 
125 }
126 
127 
129 template <class ImageIterator, class ImageAccessor,
130  class AlphaIterator, class AlphaAccessor>
131 static void
132 createScalarATiffImage(ImageIterator upperleft, ImageIterator lowerright,
133  ImageAccessor a,
134  AlphaIterator alphaUpperleft, AlphaAccessor alphaA,
135  vigra::TiffImage * tiff, int sampleformat)
136 {
137  typedef typename ImageAccessor::value_type PixelType;
138 
139  int w = lowerright.x - upperleft.x;
140  int h = lowerright.y - upperleft.y;
141 
142  TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w);
143  TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h);
144  TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, sizeof(PixelType) * 8);
145  TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 2);
146  TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
147  TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, sampleformat);
148  TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
149  TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, 1);
150 
151  // for alpha stuff, do not uses premultilied data
152  // We do not want to throw away data by premultiplying
153  uint16_t nextra_samples = 1;
154  uint16_t extra_samples = EXTRASAMPLE_UNASSALPHA;
155  TIFFSetField (tiff, TIFFTAG_EXTRASAMPLES, nextra_samples, &extra_samples);
156 
157  int bufsize = TIFFScanlineSize(tiff);
158  tdata_t * buf = new tdata_t[bufsize];
159 
160  ImageIterator ys(upperleft);
161  AlphaIterator ya(alphaUpperleft);
162 
163  try
164  {
165  for(int y=0; y<h; ++y, ++ys.y, ++ya.y)
166  {
167  PixelType * pg = (PixelType *)buf;
168  PixelType * alpha = pg+1;
169 
170  ImageIterator xs(ys);
171  AlphaIterator xa(ya);
172 
173  for(int x=0; x<w; ++x, ++xs.x, pg+=2, alpha+=2, ++xa.x)
174  {
175  *pg = a(xs);
176  *alpha = alphaA(xa);
177  }
178  TIFFWriteScanline(tiff, buf, y);
179  }
180  }
181  catch(...)
182  {
183  delete[] buf;
184  throw;
185  }
186  delete[] buf;
187 }
188 
190 template <class ImageIterator, class ImageAccessor,
191  class AlphaIterator, class AlphaAccessor>
192 void
193 createRGBATiffImage(ImageIterator upperleft, ImageIterator lowerright,
194  ImageAccessor a,
195  AlphaIterator alphaUpperleft, AlphaAccessor alphaA,
196  vigra::TiffImage * tiff, int sampleformat)
197 {
198  typedef typename ImageAccessor::value_type PType;
199  typedef typename PType::value_type PixelType;
200 // typedef typename ImageAccessor::value_type PixelType;
201  int w = lowerright.x - upperleft.x;
202  int h = lowerright.y - upperleft.y;
203 
204  TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w);
205  TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h);
206  TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, sizeof(PixelType) * 8);
207  TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 4);
208  TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
209  TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, sampleformat);
210  TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
211  TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, 1);
212 
213  // for alpha stuff, do not uses premultilied data
214  // We do not want to throw away data & accuracy by premultiplying
215  uint16_t nextra_samples = 1;
216  uint16_t extra_samples = EXTRASAMPLE_UNASSALPHA;
217  TIFFSetField (tiff, TIFFTAG_EXTRASAMPLES, nextra_samples, &extra_samples);
218 
219  int bufsize = TIFFScanlineSize(tiff);
220  tdata_t * buf = new tdata_t[bufsize];
221 
222  ImageIterator ys(upperleft);
223  AlphaIterator ya(alphaUpperleft);
224 
225  try
226  {
227  for(int y=0; y<h; ++y, ++ys.y, ++ya.y)
228  {
229  PixelType * pr = (PixelType *)buf;
230  PixelType * pg = pr+1;
231  PixelType * pb = pg+1;
232  PixelType * alpha = pb+1;
233 
234  ImageIterator xs(ys);
235  AlphaIterator xa(ya);
236 
237  for(int x=0; x<w; ++x, ++xs.x, pr+=4, pg+=4, pb+=4, alpha+=4, ++xa.x)
238  {
239  *pr = a.red(xs);
240  *pg = a.green(xs);
241  *pb = a.blue(xs);
242  *alpha = alphaA(xa);
243  }
244  TIFFWriteScanline(tiff, buf, y);
245  }
246  }
247  catch(...)
248  {
249  delete[] buf;
250  throw;
251  }
252  delete[] buf;
253 }
254 
255 // try to add stuff the vigra way
256 // This are constructor classes, to do a kind of compile time switch
257 // for the different image types.
258 template <class T>
260 
261 // 8 bit images
262 template <>
263 struct CreateAlphaTiffImage<vigra::RGBValue<unsigned char> >
264 {
265  template <class ImageIterator, class ImageAccessor,
266  class AlphaIterator, class AlphaAccessor>
267  static void exec(ImageIterator iUL, ImageIterator iLR,
268  ImageAccessor iA,
269  AlphaIterator aUL,
270  AlphaAccessor aA,
271  vigra::TiffImage * tiff)
272  {
273  createRGBATiffImage(iUL, iLR, iA, aUL, aA, tiff, SAMPLEFORMAT_UINT);
274  }
275 };
276 
277 // 16 bit
278 template <>
279 struct CreateAlphaTiffImage<vigra::RGBValue<short> >
280 {
281  template <class ImageIterator, class ImageAccessor,
282  class AlphaIterator, class AlphaAccessor>
283  static void exec(ImageIterator iUL, ImageIterator iLR,
284  ImageAccessor iA,
285  AlphaIterator aUL,
286  AlphaAccessor aA,
287  vigra::TiffImage * tiff)
288  {
290  AlphaAccessor>
291  mA(vigra::ScalarIntensityTransform<short>(128), aA);
292  createRGBATiffImage(iUL, iLR, iA, aUL, mA,
293  tiff, SAMPLEFORMAT_INT);
294  }
295 };
296 
297 template <>
298 struct CreateAlphaTiffImage<vigra::RGBValue<unsigned short> >
299 {
300  template <class ImageIterator, class ImageAccessor,
301  class AlphaIterator, class AlphaAccessor>
302  static void exec(ImageIterator iUL, ImageIterator iLR,
303  ImageAccessor iA,
304  AlphaIterator aUL,
305  AlphaAccessor aA,
306  vigra::TiffImage * tiff)
307  {
309  mA(vigra::ScalarIntensityTransform<unsigned short>(256), aA);
310  createRGBATiffImage(iUL, iLR, iA, aUL, mA,
311  tiff, SAMPLEFORMAT_UINT);
312  }
313 };
314 
315 
316 // 32 bit
317 template <>
318 struct CreateAlphaTiffImage<vigra::RGBValue<int> >
319 {
320  template <class ImageIterator, class ImageAccessor,
321  class AlphaIterator, class AlphaAccessor>
322  static void exec(ImageIterator iUL, ImageIterator iLR,
323  ImageAccessor iA,
324  AlphaIterator aUL,
325  AlphaAccessor aA,
326  vigra::TiffImage * tiff)
327  {
329  mA(vigra::ScalarIntensityTransform<int>(8388608), aA);
330  createRGBATiffImage(iUL, iLR, iA, aUL, mA,
331  tiff, SAMPLEFORMAT_INT);
332  }
333 };
334 
335 template <>
336 struct CreateAlphaTiffImage<vigra::RGBValue<unsigned int> >
337 {
338  template <class ImageIterator, class ImageAccessor,
339  class AlphaIterator, class AlphaAccessor>
340  static void exec(ImageIterator iUL, ImageIterator iLR,
341  ImageAccessor iA,
342  AlphaIterator aUL,
343  AlphaAccessor aA,
344  vigra::TiffImage * tiff)
345  {
347  mA(vigra::ScalarIntensityTransform<unsigned int>(16777216), aA);
348  createRGBATiffImage(iUL, iLR, iA, aUL, mA,
349  tiff, SAMPLEFORMAT_UINT);
350  }
351 };
352 
353 // float
354 template <>
355 struct CreateAlphaTiffImage<vigra::RGBValue<float> >
356 {
357  template <class ImageIterator, class ImageAccessor,
358  class AlphaIterator, class AlphaAccessor>
359  static void exec(ImageIterator iUL, ImageIterator iLR,
360  ImageAccessor iA,
361  AlphaIterator aUL,
362  AlphaAccessor aA,
363  vigra::TiffImage * tiff)
364  {
366  mA(vigra::ScalarIntensityTransform<float>(1.0f/255), aA);
367  createRGBATiffImage(iUL, iLR, iA, aUL, mA,
368  tiff, SAMPLEFORMAT_IEEEFP);
369  }
370 };
371 
372 // double
373 template <>
374 struct CreateAlphaTiffImage<vigra::RGBValue<double> >
375 {
376  template <class ImageIterator, class ImageAccessor,
377  class AlphaIterator, class AlphaAccessor>
378  static void exec(ImageIterator iUL, ImageIterator iLR,
379  ImageAccessor iA,
380  AlphaIterator aUL,
381  AlphaAccessor aA,
382  vigra::TiffImage * tiff)
383  {
385  mA(vigra::ScalarIntensityTransform<double>(1.0f/255),aA);
386  createRGBATiffImage(iUL, iLR, iA, aUL, mA,
387  tiff, SAMPLEFORMAT_IEEEFP);
388  }
389 };
390 
391 // ================================================================
392 // for scalar images
393 // ================================================================
394 
395 // 8 bit images
396 template <>
397 struct CreateAlphaTiffImage<unsigned char>
398 {
399  template <class ImageIterator, class ImageAccessor,
400  class AlphaIterator, class AlphaAccessor>
401  static void exec(ImageIterator iUL, ImageIterator iLR,
402  ImageAccessor iA,
403  AlphaIterator aUL,
404  AlphaAccessor aA,
405  vigra::TiffImage * tiff)
406  {
407  createScalarATiffImage(iUL, iLR, iA, aUL, aA, tiff, SAMPLEFORMAT_UINT);
408  }
409 };
410 
411 // 16 bit
412 template <>
413 struct CreateAlphaTiffImage<short>
414 {
415  template <class ImageIterator, class ImageAccessor,
416  class AlphaIterator, class AlphaAccessor>
417  static void exec(ImageIterator iUL, ImageIterator iLR,
418  ImageAccessor iA,
419  AlphaIterator aUL,
420  AlphaAccessor aA,
421  vigra::TiffImage * tiff)
422  {
424  mA(vigra::ScalarIntensityTransform<short>(128), aA);
425  createScalarATiffImage(iUL, iLR, iA, aUL, mA, tiff, SAMPLEFORMAT_INT);
426  }
427 };
428 template <>
429 struct CreateAlphaTiffImage<unsigned short>
430 {
431  template <class ImageIterator, class ImageAccessor,
432  class AlphaIterator, class AlphaAccessor>
433  static void exec(ImageIterator iUL, ImageIterator iLR,
434  ImageAccessor iA,
435  AlphaIterator aUL,
436  AlphaAccessor aA,
437  vigra::TiffImage * tiff)
438  {
440  mA(vigra::ScalarIntensityTransform<unsigned short>(256), aA);
441  createScalarATiffImage(iUL, iLR, iA, aUL, mA, tiff, SAMPLEFORMAT_UINT);
442  }
443 };
444 
445 // 32 bit
446 template <>
448 {
449  template <class ImageIterator, class ImageAccessor,
450  class AlphaIterator, class AlphaAccessor>
451  static void exec(ImageIterator iUL, ImageIterator iLR,
452  ImageAccessor iA,
453  AlphaIterator aUL,
454  AlphaAccessor aA,
455  vigra::TiffImage * tiff)
456  {
458  mA(vigra::ScalarIntensityTransform<int>(8388608), aA);
459  createScalarATiffImage(iUL, iLR, iA, aUL, mA, tiff, SAMPLEFORMAT_INT);
460  }
461 };
462 
463 template <>
464 struct CreateAlphaTiffImage<unsigned int>
465 {
466  template <class ImageIterator, class ImageAccessor,
467  class AlphaIterator, class AlphaAccessor>
468  static void exec(ImageIterator iUL, ImageIterator iLR,
469  ImageAccessor iA,
470  AlphaIterator aUL,
471  AlphaAccessor aA,
472  vigra::TiffImage * tiff)
473  {
475  mA(vigra::ScalarIntensityTransform<unsigned int>(16777216), aA);
476  createScalarATiffImage(iUL, iLR, iA, aUL, mA, tiff, SAMPLEFORMAT_UINT);
477  }
478 };
479 
480 // float
481 template <>
482 struct CreateAlphaTiffImage<float>
483 {
484  template <class ImageIterator, class ImageAccessor,
485  class AlphaIterator, class AlphaAccessor>
486  static void exec(ImageIterator iUL, ImageIterator iLR,
487  ImageAccessor iA,
488  AlphaIterator aUL,
489  AlphaAccessor aA,
490  vigra::TiffImage * tiff)
491  {
493  mA(vigra::ScalarIntensityTransform<float>(1.0f/255), aA);
494  createScalarATiffImage(iUL, iLR, iA, aUL, mA, tiff, SAMPLEFORMAT_IEEEFP);
495  }
496 };
497 
498 // double
499 template <>
500 struct CreateAlphaTiffImage<double>
501 {
502  template <class ImageIterator, class ImageAccessor,
503  class AlphaIterator, class AlphaAccessor>
504  static void exec(ImageIterator iUL, ImageIterator iLR,
505  ImageAccessor iA,
506  AlphaIterator aUL,
507  AlphaAccessor aA,
508  vigra::TiffImage * tiff)
509  {
511  mA(vigra::ScalarIntensityTransform<double>(1.0f/255), aA);
512  createScalarATiffImage(iUL, iLR, iA, aUL, mA, tiff, SAMPLEFORMAT_IEEEFP);
513  }
514 };
515 
516 // ============================================================
517 // ============================================================
518 
519 template <class ImageIterator, class ImageAccessor,
520  class AlphaIterator, class AlphaAccessor>
521 inline void
522 createAlphaTiffImage(ImageIterator upperleft, ImageIterator lowerright,
523  ImageAccessor a,
524  AlphaIterator alphaUpperleft, AlphaAccessor alphaA,
525  vigra::TiffImage * tiff)
526 {
527  // call right constructor class for this image type
529  exec(upperleft, lowerright, a,
530  alphaUpperleft, alphaA, tiff);
531 }
532 
542 template <class ImageIterator, class ImageAccessor,
543  class AlphaIterator, class BImageAccessor>
544 
545 void
546 createAlphaTiffImage(vigra::triple<ImageIterator, ImageIterator, ImageAccessor> src,
547  vigra::pair<AlphaIterator, BImageAccessor> alpha,
548  vigra::TiffImage * tiff)
549 {
550  createAlphaTiffImage(src.first, src.second, src.third,
551  alpha.first, alpha.second, tiff);
552 }
553 
554 
555 
556 //***************************************************************************
557 //
558 // functions to read tiff files with a single alpha channel,
559 // multiple layers and offsets.
560 //
561 //***************************************************************************
562 
563 
564 }
565 
566 #endif // _TIFFUTILS_H
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:504
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:283
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:322
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:267
#define DEBUG_ASSERT(cond)
Definition: utils.h:80
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:433
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:451
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:468
void createAlphaTiffImage(ImageIterator upperleft, ImageIterator lowerright, ImageAccessor a, AlphaIterator alphaUpperleft, AlphaAccessor alphaA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:522
IMPEX double h[25][1024]
Definition: emor.cpp:169
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:401
void createTiffDirectory(vigra::TiffImage *tiff, const std::string &pagename, const std::string &documentname, const std::string comp, uint16_t page, uint16_t nImg, vigra::Diff2D offset, vigra::Size2D fullSize, const vigra::ImageExportInfo::ICCProfile &icc)
write a new Tiff directory, for a new layer
Definition: tiffUtils.h:58
static void createScalarATiffImage(ImageIterator upperleft, ImageIterator lowerright, ImageAccessor a, AlphaIterator alphaUpperleft, AlphaAccessor alphaA, vigra::TiffImage *tiff, int sampleformat)
internal function to create a scalar tiff image with alpha channel
Definition: tiffUtils.h:132
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:486
This class can be used to apply a function when reading the input image.
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:359
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:417
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:340
void createRGBATiffImage(ImageIterator upperleft, ImageIterator lowerright, ImageAccessor a, AlphaIterator alphaUpperleft, AlphaAccessor alphaA, vigra::TiffImage *tiff, int sampleformat)
internal function to create a RGB tiff image with alpha channel
Definition: tiffUtils.h:193
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:378
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:302