Hugin trunk 0.1
Loading...
Searching...
No Matches
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
40namespace vigra_ext {
41
42
43//***************************************************************************
44//
45// functions to write tiff files with a single alpha channel.
46//
47//***************************************************************************
48
58inline void createTiffDirectory(vigra::TiffImage * tiff, const std::string & pagename,
59 const std::string & documentname,
60 const std::string comp,
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) {
78 }
80 TIFFSetField (tiff, TIFFTAG_PAGENUMBER, (unsigned short)page, (unsigned short)nImg);
81 }
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.
97
98 // save input name.
101 //
102 TIFFSetField (tiff, TIFFTAG_IMAGEDESCRIPTION, "stitched with hugin");
103
104 // set compression
105 unsigned short tiffcomp;
106 if ( comp == "JPEG" )
108 else if ( comp == "LZW" )
110 else if ( comp == "DEFLATE" )
112 else if ( comp == "PACKBITS" )
114 else
116
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
129template <class ImageIterator, class ImageAccessor,
130 class AlphaIterator, class AlphaAccessor>
131static void
133 ImageAccessor a,
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
144 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, sizeof(PixelType) * 8);
150
151 // for alpha stuff, do not uses premultilied data
152 // We do not want to throw away data by premultiplying
156
158 tdata_t * buf = new tdata_t[bufsize];
159
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
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 }
179 }
180 }
181 catch(...)
182 {
183 delete[] buf;
184 throw;
185 }
186 delete[] buf;
187}
188
190template <class ImageIterator, class ImageAccessor,
191 class AlphaIterator, class AlphaAccessor>
192void
194 ImageAccessor a,
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
206 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, sizeof(PixelType) * 8);
212
213 // for alpha stuff, do not uses premultilied data
214 // We do not want to throw away data & accuracy by premultiplying
218
220 tdata_t * buf = new tdata_t[bufsize];
221
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
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 }
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.
258template <class T>
260
261// 8 bit images
262template <>
263struct CreateAlphaTiffImage<vigra::RGBValue<unsigned char> >
264{
265 template <class ImageIterator, class ImageAccessor,
266 class AlphaIterator, class AlphaAccessor>
268 ImageAccessor iA,
271 vigra::TiffImage * tiff)
272 {
274 }
275};
276
277// 16 bit
278template <>
280{
281 template <class ImageIterator, class ImageAccessor,
282 class AlphaIterator, class AlphaAccessor>
284 ImageAccessor iA,
287 vigra::TiffImage * tiff)
288 {
291 mA(vigra::ScalarIntensityTransform<short>(128), aA);
294 }
295};
296
297template <>
298struct CreateAlphaTiffImage<vigra::RGBValue<unsigned short> >
299{
300 template <class ImageIterator, class ImageAccessor,
301 class AlphaIterator, class AlphaAccessor>
303 ImageAccessor iA,
306 vigra::TiffImage * tiff)
307 {
309 mA(vigra::ScalarIntensityTransform<unsigned short>(256), aA);
312 }
313};
314
315
316// 32 bit
317template <>
319{
320 template <class ImageIterator, class ImageAccessor,
321 class AlphaIterator, class AlphaAccessor>
323 ImageAccessor iA,
326 vigra::TiffImage * tiff)
327 {
329 mA(vigra::ScalarIntensityTransform<int>(8388608), aA);
332 }
333};
334
335template <>
336struct CreateAlphaTiffImage<vigra::RGBValue<unsigned int> >
337{
338 template <class ImageIterator, class ImageAccessor,
339 class AlphaIterator, class AlphaAccessor>
341 ImageAccessor iA,
344 vigra::TiffImage * tiff)
345 {
347 mA(vigra::ScalarIntensityTransform<unsigned int>(16777216), aA);
350 }
351};
352
353// float
354template <>
356{
357 template <class ImageIterator, class ImageAccessor,
358 class AlphaIterator, class AlphaAccessor>
360 ImageAccessor iA,
363 vigra::TiffImage * tiff)
364 {
366 mA(vigra::ScalarIntensityTransform<float>(1.0f/255), aA);
369 }
370};
371
372// double
373template <>
375{
376 template <class ImageIterator, class ImageAccessor,
377 class AlphaIterator, class AlphaAccessor>
379 ImageAccessor iA,
382 vigra::TiffImage * tiff)
383 {
385 mA(vigra::ScalarIntensityTransform<double>(1.0f/255),aA);
388 }
389};
390
391// ================================================================
392// for scalar images
393// ================================================================
394
395// 8 bit images
396template <>
398{
399 template <class ImageIterator, class ImageAccessor,
400 class AlphaIterator, class AlphaAccessor>
402 ImageAccessor iA,
405 vigra::TiffImage * tiff)
406 {
408 }
409};
410
411// 16 bit
412template <>
414{
415 template <class ImageIterator, class ImageAccessor,
416 class AlphaIterator, class AlphaAccessor>
418 ImageAccessor iA,
421 vigra::TiffImage * tiff)
422 {
424 mA(vigra::ScalarIntensityTransform<short>(128), aA);
426 }
427};
428template <>
430{
431 template <class ImageIterator, class ImageAccessor,
432 class AlphaIterator, class AlphaAccessor>
434 ImageAccessor iA,
437 vigra::TiffImage * tiff)
438 {
440 mA(vigra::ScalarIntensityTransform<unsigned short>(256), aA);
442 }
443};
444
445// 32 bit
446template <>
448{
449 template <class ImageIterator, class ImageAccessor,
450 class AlphaIterator, class AlphaAccessor>
452 ImageAccessor iA,
455 vigra::TiffImage * tiff)
456 {
458 mA(vigra::ScalarIntensityTransform<int>(8388608), aA);
460 }
461};
462
463template <>
465{
466 template <class ImageIterator, class ImageAccessor,
467 class AlphaIterator, class AlphaAccessor>
469 ImageAccessor iA,
472 vigra::TiffImage * tiff)
473 {
475 mA(vigra::ScalarIntensityTransform<unsigned int>(16777216), aA);
477 }
478};
479
480// float
481template <>
483{
484 template <class ImageIterator, class ImageAccessor,
485 class AlphaIterator, class AlphaAccessor>
487 ImageAccessor iA,
490 vigra::TiffImage * tiff)
491 {
493 mA(vigra::ScalarIntensityTransform<float>(1.0f/255), aA);
495 }
496};
497
498// double
499template <>
501{
502 template <class ImageIterator, class ImageAccessor,
503 class AlphaIterator, class AlphaAccessor>
505 ImageAccessor iA,
508 vigra::TiffImage * tiff)
509 {
511 mA(vigra::ScalarIntensityTransform<double>(1.0f/255), aA);
513 }
514};
515
516// ============================================================
517// ============================================================
518
519template <class ImageIterator, class ImageAccessor,
520 class AlphaIterator, class AlphaAccessor>
521inline void
523 ImageAccessor a,
525 vigra::TiffImage * tiff)
526{
527 // call right constructor class for this image type
531}
532
542template <class ImageIterator, class ImageAccessor,
543 class AlphaIterator, class BImageAccessor>
544
545void
546createAlphaTiffImage(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
This class can be used to apply a function when reading the input image.
#define DEBUG_ASSERT(cond)
Definition utils.h:80
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
void createAlphaTiffImage(ImageIterator upperleft, ImageIterator lowerright, ImageAccessor a, AlphaIterator alphaUpperleft, AlphaAccessor alphaA, vigra::TiffImage *tiff)
Definition tiffUtils.h:522
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
Implementation of fast vector type with support of linear algebra operations Copyright (C) 2009 Lukáš...
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:486
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:417
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition tiffUtils.h:401
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition tiffUtils.h:468
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:378
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:322
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:267
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition tiffUtils.h:340
static void exec(ImageIterator iUL, ImageIterator iLR, ImageAccessor iA, AlphaIterator aUL, AlphaAccessor aA, vigra::TiffImage *tiff)
Definition tiffUtils.h:302
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
Definition threshold.h:41