00001
00026 #ifndef _TIFFUTILS_H
00027 #define _TIFFUTILS_H
00028
00029 #include <vigra/tiff.hxx>
00030 #include <vigra/imageinfo.hxx>
00031 #include <vigra/transformimage.hxx>
00032 #include <vigra/functorexpression.hxx>
00033
00034 #include <vigra_ext/FunctorAccessor.h>
00035
00036 #include <tiffio.h>
00037
00038
00039 namespace vigra_ext {
00040
00041
00042
00043
00044
00045
00046
00047
00057 inline void createTiffDirectory(vigra::TiffImage * tiff, const std::string & pagename,
00058 const std::string & documentname,
00059 const std::string comp,
00060 uint16 page, uint16 nImg,
00061 vigra::Diff2D offset,
00062 vigra::Size2D fullSize,
00063 const vigra::ImageExportInfo::ICCProfile & icc)
00064 {
00065 const float dpi = 150;
00066
00067
00068
00069
00070
00071
00072 if (nImg > 1) {
00073
00074
00075 if (page > 1) {
00076 TIFFCreateDirectory (tiff);
00077 }
00078 TIFFSetField (tiff, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
00079 TIFFSetField (tiff, TIFFTAG_PAGENUMBER, (unsigned short)page, (unsigned short)nImg);
00080 }
00081 TIFFSetField (tiff, TIFFTAG_XRESOLUTION, (float) dpi);
00082 TIFFSetField (tiff, TIFFTAG_YRESOLUTION, (float) dpi);
00083
00084 DEBUG_ASSERT(offset.x >= 0);
00085 DEBUG_ASSERT(offset.y >= 0);
00086 TIFFSetField (tiff, TIFFTAG_XPOSITION, (float)(offset.x / dpi));
00087 TIFFSetField (tiff, TIFFTAG_YPOSITION, (float)(offset.y / dpi));
00088
00089
00090
00091
00092
00093
00094 TIFFSetField(tiff, TIFFTAG_PIXAR_IMAGEFULLWIDTH, fullSize.x);
00095 TIFFSetField(tiff, TIFFTAG_PIXAR_IMAGEFULLLENGTH, fullSize.y);
00096
00097
00098 TIFFSetField (tiff, TIFFTAG_DOCUMENTNAME, documentname.c_str());
00099 TIFFSetField (tiff, TIFFTAG_PAGENAME, pagename.c_str() );
00100
00101 TIFFSetField (tiff, TIFFTAG_IMAGEDESCRIPTION, "stitched with hugin");
00102
00103
00104 unsigned short tiffcomp;
00105 if ( comp == "JPEG" )
00106 tiffcomp = COMPRESSION_OJPEG;
00107 else if ( comp == "LZW" )
00108 tiffcomp = COMPRESSION_LZW;
00109 else if ( comp == "DEFLATE" )
00110 tiffcomp = COMPRESSION_DEFLATE;
00111 else if ( comp == "PACKBITS" )
00112 tiffcomp = COMPRESSION_PACKBITS;
00113 else
00114 tiffcomp = COMPRESSION_NONE;
00115
00116 TIFFSetField(tiff, TIFFTAG_COMPRESSION, tiffcomp);
00117
00118
00119 if (icc.size() > 0) {
00120 TIFFSetField(tiff, TIFFTAG_ICCPROFILE, icc.size(), icc.front());
00121 }
00122
00123 }
00124
00125
00127 template <class ImageIterator, class ImageAccessor,
00128 class AlphaIterator, class AlphaAccessor>
00129 static void
00130 createScalarATiffImage(ImageIterator upperleft, ImageIterator lowerright,
00131 ImageAccessor a,
00132 AlphaIterator alphaUpperleft, AlphaAccessor alphaA,
00133 vigra::TiffImage * tiff, int sampleformat)
00134 {
00135 typedef typename ImageAccessor::value_type PixelType;
00136
00137 int w = lowerright.x - upperleft.x;
00138 int h = lowerright.y - upperleft.y;
00139
00140 TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w);
00141 TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h);
00142 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, sizeof(PixelType) * 8);
00143 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 2);
00144 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
00145 TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, sampleformat);
00146 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
00147 TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, 1);
00148
00149
00150
00151 uint16 nextra_samples = 1;
00152 uint16 extra_samples = EXTRASAMPLE_UNASSALPHA;
00153 TIFFSetField (tiff, TIFFTAG_EXTRASAMPLES, nextra_samples, &extra_samples);
00154
00155 int bufsize = TIFFScanlineSize(tiff);
00156 tdata_t * buf = new tdata_t[bufsize];
00157
00158 ImageIterator ys(upperleft);
00159 AlphaIterator ya(alphaUpperleft);
00160
00161 try
00162 {
00163 for(int y=0; y<h; ++y, ++ys.y, ++ya.y)
00164 {
00165 PixelType * pg = (PixelType *)buf;
00166 PixelType * alpha = pg+1;
00167
00168 ImageIterator xs(ys);
00169 AlphaIterator xa(ya);
00170
00171 for(int x=0; x<w; ++x, ++xs.x, pg+=2, alpha+=2, ++xa.x)
00172 {
00173 *pg = a(xs);
00174 *alpha = alphaA(xa);
00175 }
00176 TIFFWriteScanline(tiff, buf, y);
00177 }
00178 }
00179 catch(...)
00180 {
00181 delete[] buf;
00182 throw;
00183 }
00184 delete[] buf;
00185 }
00186
00188 template <class ImageIterator, class ImageAccessor,
00189 class AlphaIterator, class AlphaAccessor>
00190 void
00191 createRGBATiffImage(ImageIterator upperleft, ImageIterator lowerright,
00192 ImageAccessor a,
00193 AlphaIterator alphaUpperleft, AlphaAccessor alphaA,
00194 vigra::TiffImage * tiff, int sampleformat)
00195 {
00196 typedef typename ImageAccessor::value_type PType;
00197 typedef typename PType::value_type PixelType;
00198
00199 int w = lowerright.x - upperleft.x;
00200 int h = lowerright.y - upperleft.y;
00201
00202 TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w);
00203 TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h);
00204 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, sizeof(PixelType) * 8);
00205 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 4);
00206 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
00207 TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, sampleformat);
00208 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
00209 TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, 1);
00210
00211
00212
00213 uint16 nextra_samples = 1;
00214 uint16 extra_samples = EXTRASAMPLE_UNASSALPHA;
00215 TIFFSetField (tiff, TIFFTAG_EXTRASAMPLES, nextra_samples, &extra_samples);
00216
00217 int bufsize = TIFFScanlineSize(tiff);
00218 tdata_t * buf = new tdata_t[bufsize];
00219
00220 ImageIterator ys(upperleft);
00221 AlphaIterator ya(alphaUpperleft);
00222
00223 try
00224 {
00225 for(int y=0; y<h; ++y, ++ys.y, ++ya.y)
00226 {
00227 PixelType * pr = (PixelType *)buf;
00228 PixelType * pg = pr+1;
00229 PixelType * pb = pg+1;
00230 PixelType * alpha = pb+1;
00231
00232 ImageIterator xs(ys);
00233 AlphaIterator xa(ya);
00234
00235 for(int x=0; x<w; ++x, ++xs.x, pr+=4, pg+=4, pb+=4, alpha+=4, ++xa.x)
00236 {
00237 *pr = a.red(xs);
00238 *pg = a.green(xs);
00239 *pb = a.blue(xs);
00240 *alpha = alphaA(xa);
00241 }
00242 TIFFWriteScanline(tiff, buf, y);
00243 }
00244 }
00245 catch(...)
00246 {
00247 delete[] buf;
00248 throw;
00249 }
00250 delete[] buf;
00251 }
00252
00253
00254
00255
00256 template <class T>
00257 struct CreateAlphaTiffImage;
00258
00259
00260 template <>
00261 struct CreateAlphaTiffImage<vigra::RGBValue<unsigned char> >
00262 {
00263 template <class ImageIterator, class ImageAccessor,
00264 class AlphaIterator, class AlphaAccessor>
00265 static void exec(ImageIterator iUL, ImageIterator iLR,
00266 ImageAccessor iA,
00267 AlphaIterator aUL,
00268 AlphaAccessor aA,
00269 vigra::TiffImage * tiff)
00270 {
00271 createRGBATiffImage(iUL, iLR, iA, aUL, aA, tiff, SAMPLEFORMAT_UINT);
00272 }
00273 };
00274
00275
00276 template <>
00277 struct CreateAlphaTiffImage<vigra::RGBValue<short> >
00278 {
00279 template <class ImageIterator, class ImageAccessor,
00280 class AlphaIterator, class AlphaAccessor>
00281 static void exec(ImageIterator iUL, ImageIterator iLR,
00282 ImageAccessor iA,
00283 AlphaIterator aUL,
00284 AlphaAccessor aA,
00285 vigra::TiffImage * tiff)
00286 {
00287 vigra_ext::ReadFunctorAccessor<vigra::ScalarIntensityTransform<short>,
00288 AlphaAccessor>
00289 mA(vigra::ScalarIntensityTransform<short>(128), aA);
00290 createRGBATiffImage(iUL, iLR, iA, aUL, mA,
00291 tiff, SAMPLEFORMAT_INT);
00292 }
00293 };
00294
00295 template <>
00296 struct CreateAlphaTiffImage<vigra::RGBValue<unsigned short> >
00297 {
00298 template <class ImageIterator, class ImageAccessor,
00299 class AlphaIterator, class AlphaAccessor>
00300 static void exec(ImageIterator iUL, ImageIterator iLR,
00301 ImageAccessor iA,
00302 AlphaIterator aUL,
00303 AlphaAccessor aA,
00304 vigra::TiffImage * tiff)
00305 {
00306 vigra_ext::ReadFunctorAccessor<vigra::ScalarIntensityTransform<unsigned short>, AlphaAccessor>
00307 mA(vigra::ScalarIntensityTransform<unsigned short>(256), aA);
00308 createRGBATiffImage(iUL, iLR, iA, aUL, mA,
00309 tiff, SAMPLEFORMAT_UINT);
00310 }
00311 };
00312
00313
00314
00315 template <>
00316 struct CreateAlphaTiffImage<vigra::RGBValue<int> >
00317 {
00318 template <class ImageIterator, class ImageAccessor,
00319 class AlphaIterator, class AlphaAccessor>
00320 static void exec(ImageIterator iUL, ImageIterator iLR,
00321 ImageAccessor iA,
00322 AlphaIterator aUL,
00323 AlphaAccessor aA,
00324 vigra::TiffImage * tiff)
00325 {
00326 vigra_ext::ReadFunctorAccessor<vigra::ScalarIntensityTransform<int>, AlphaAccessor>
00327 mA(vigra::ScalarIntensityTransform<int>(8388608), aA);
00328 createRGBATiffImage(iUL, iLR, iA, aUL, mA,
00329 tiff, SAMPLEFORMAT_INT);
00330 }
00331 };
00332
00333 template <>
00334 struct CreateAlphaTiffImage<vigra::RGBValue<unsigned int> >
00335 {
00336 template <class ImageIterator, class ImageAccessor,
00337 class AlphaIterator, class AlphaAccessor>
00338 static void exec(ImageIterator iUL, ImageIterator iLR,
00339 ImageAccessor iA,
00340 AlphaIterator aUL,
00341 AlphaAccessor aA,
00342 vigra::TiffImage * tiff)
00343 {
00344 vigra_ext::ReadFunctorAccessor<vigra::ScalarIntensityTransform<unsigned int>, AlphaAccessor>
00345 mA(vigra::ScalarIntensityTransform<unsigned int>(16777216), aA);
00346 createRGBATiffImage(iUL, iLR, iA, aUL, mA,
00347 tiff, SAMPLEFORMAT_UINT);
00348 }
00349 };
00350
00351
00352 template <>
00353 struct CreateAlphaTiffImage<vigra::RGBValue<float> >
00354 {
00355 template <class ImageIterator, class ImageAccessor,
00356 class AlphaIterator, class AlphaAccessor>
00357 static void exec(ImageIterator iUL, ImageIterator iLR,
00358 ImageAccessor iA,
00359 AlphaIterator aUL,
00360 AlphaAccessor aA,
00361 vigra::TiffImage * tiff)
00362 {
00363 vigra_ext::ReadFunctorAccessor<vigra::ScalarIntensityTransform<float>, AlphaAccessor>
00364 mA(vigra::ScalarIntensityTransform<float>(1.0f/255), aA);
00365 createRGBATiffImage(iUL, iLR, iA, aUL, mA,
00366 tiff, SAMPLEFORMAT_IEEEFP);
00367 }
00368 };
00369
00370
00371 template <>
00372 struct CreateAlphaTiffImage<vigra::RGBValue<double> >
00373 {
00374 template <class ImageIterator, class ImageAccessor,
00375 class AlphaIterator, class AlphaAccessor>
00376 static void exec(ImageIterator iUL, ImageIterator iLR,
00377 ImageAccessor iA,
00378 AlphaIterator aUL,
00379 AlphaAccessor aA,
00380 vigra::TiffImage * tiff)
00381 {
00382 vigra_ext::ReadFunctorAccessor<vigra::ScalarIntensityTransform<double>, AlphaAccessor>
00383 mA(vigra::ScalarIntensityTransform<double>(1.0f/255),aA);
00384 createRGBATiffImage(iUL, iLR, iA, aUL, mA,
00385 tiff, SAMPLEFORMAT_IEEEFP);
00386 }
00387 };
00388
00389
00390
00391
00392
00393
00394 template <>
00395 struct CreateAlphaTiffImage<unsigned char>
00396 {
00397 template <class ImageIterator, class ImageAccessor,
00398 class AlphaIterator, class AlphaAccessor>
00399 static void exec(ImageIterator iUL, ImageIterator iLR,
00400 ImageAccessor iA,
00401 AlphaIterator aUL,
00402 AlphaAccessor aA,
00403 vigra::TiffImage * tiff)
00404 {
00405 createScalarATiffImage(iUL, iLR, iA, aUL, aA, tiff, SAMPLEFORMAT_UINT);
00406 }
00407 };
00408
00409
00410 template <>
00411 struct CreateAlphaTiffImage<short>
00412 {
00413 template <class ImageIterator, class ImageAccessor,
00414 class AlphaIterator, class AlphaAccessor>
00415 static void exec(ImageIterator iUL, ImageIterator iLR,
00416 ImageAccessor iA,
00417 AlphaIterator aUL,
00418 AlphaAccessor aA,
00419 vigra::TiffImage * tiff)
00420 {
00421 vigra_ext::ReadFunctorAccessor<vigra::ScalarIntensityTransform<short>, AlphaAccessor>
00422 mA(vigra::ScalarIntensityTransform<short>(128), aA);
00423 createScalarATiffImage(iUL, iLR, iA, aUL, mA, tiff, SAMPLEFORMAT_INT);
00424 }
00425 };
00426 template <>
00427 struct CreateAlphaTiffImage<unsigned short>
00428 {
00429 template <class ImageIterator, class ImageAccessor,
00430 class AlphaIterator, class AlphaAccessor>
00431 static void exec(ImageIterator iUL, ImageIterator iLR,
00432 ImageAccessor iA,
00433 AlphaIterator aUL,
00434 AlphaAccessor aA,
00435 vigra::TiffImage * tiff)
00436 {
00437 vigra_ext::ReadFunctorAccessor<vigra::ScalarIntensityTransform<unsigned short>, AlphaAccessor>
00438 mA(vigra::ScalarIntensityTransform<unsigned short>(256), aA);
00439 createScalarATiffImage(iUL, iLR, iA, aUL, mA, tiff, SAMPLEFORMAT_UINT);
00440 }
00441 };
00442
00443
00444 template <>
00445 struct CreateAlphaTiffImage<int>
00446 {
00447 template <class ImageIterator, class ImageAccessor,
00448 class AlphaIterator, class AlphaAccessor>
00449 static void exec(ImageIterator iUL, ImageIterator iLR,
00450 ImageAccessor iA,
00451 AlphaIterator aUL,
00452 AlphaAccessor aA,
00453 vigra::TiffImage * tiff)
00454 {
00455 vigra_ext::ReadFunctorAccessor<vigra::ScalarIntensityTransform<int>, AlphaAccessor>
00456 mA(vigra::ScalarIntensityTransform<int>(8388608), aA);
00457 createScalarATiffImage(iUL, iLR, iA, aUL, mA, tiff, SAMPLEFORMAT_INT);
00458 }
00459 };
00460
00461 template <>
00462 struct CreateAlphaTiffImage<unsigned int>
00463 {
00464 template <class ImageIterator, class ImageAccessor,
00465 class AlphaIterator, class AlphaAccessor>
00466 static void exec(ImageIterator iUL, ImageIterator iLR,
00467 ImageAccessor iA,
00468 AlphaIterator aUL,
00469 AlphaAccessor aA,
00470 vigra::TiffImage * tiff)
00471 {
00472 vigra_ext::ReadFunctorAccessor<vigra::ScalarIntensityTransform<unsigned int>, AlphaAccessor>
00473 mA(vigra::ScalarIntensityTransform<unsigned int>(16777216), aA);
00474 createScalarATiffImage(iUL, iLR, iA, aUL, mA, tiff, SAMPLEFORMAT_UINT);
00475 }
00476 };
00477
00478
00479 template <>
00480 struct CreateAlphaTiffImage<float>
00481 {
00482 template <class ImageIterator, class ImageAccessor,
00483 class AlphaIterator, class AlphaAccessor>
00484 static void exec(ImageIterator iUL, ImageIterator iLR,
00485 ImageAccessor iA,
00486 AlphaIterator aUL,
00487 AlphaAccessor aA,
00488 vigra::TiffImage * tiff)
00489 {
00490 vigra_ext::ReadFunctorAccessor<vigra::ScalarIntensityTransform<float>, AlphaAccessor>
00491 mA(vigra::ScalarIntensityTransform<float>(1.0f/255), aA);
00492 createScalarATiffImage(iUL, iLR, iA, aUL, mA, tiff, SAMPLEFORMAT_IEEEFP);
00493 }
00494 };
00495
00496
00497 template <>
00498 struct CreateAlphaTiffImage<double>
00499 {
00500 template <class ImageIterator, class ImageAccessor,
00501 class AlphaIterator, class AlphaAccessor>
00502 static void exec(ImageIterator iUL, ImageIterator iLR,
00503 ImageAccessor iA,
00504 AlphaIterator aUL,
00505 AlphaAccessor aA,
00506 vigra::TiffImage * tiff)
00507 {
00508 vigra_ext::ReadFunctorAccessor<vigra::ScalarIntensityTransform<double>, AlphaAccessor>
00509 mA(vigra::ScalarIntensityTransform<double>(1.0f/255), aA);
00510 createScalarATiffImage(iUL, iLR, iA, aUL, mA, tiff, SAMPLEFORMAT_IEEEFP);
00511 }
00512 };
00513
00514
00515
00516
00517 template <class ImageIterator, class ImageAccessor,
00518 class AlphaIterator, class AlphaAccessor>
00519 inline void
00520 createAlphaTiffImage(ImageIterator upperleft, ImageIterator lowerright,
00521 ImageAccessor a,
00522 AlphaIterator alphaUpperleft, AlphaAccessor alphaA,
00523 vigra::TiffImage * tiff)
00524 {
00525
00526 CreateAlphaTiffImage<typename ImageAccessor::value_type>::
00527 exec(upperleft, lowerright, a,
00528 alphaUpperleft, alphaA, tiff);
00529 }
00530
00540 template <class ImageIterator, class ImageAccessor,
00541 class AlphaIterator, class BImageAccessor>
00542
00543 void
00544 createAlphaTiffImage(vigra::triple<ImageIterator, ImageIterator, ImageAccessor> src,
00545 vigra::pair<AlphaIterator, BImageAccessor> alpha,
00546 vigra::TiffImage * tiff)
00547 {
00548 createAlphaTiffImage(src.first, src.second, src.third,
00549 alpha.first, alpha.second, tiff);
00550 }
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562 }
00563
00564 #endif // _TIFFUTILS_H