[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]
![]() |
vigra/tiff.hxx | ![]() |
---|
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 1998-2002 by Ullrich Koethe */ 00004 /* Cognitive Systems Group, University of Hamburg, Germany */ 00005 /* */ 00006 /* This file is part of the VIGRA computer vision library. */ 00007 /* ( Version 1.3.3, Aug 18 2005 ) */ 00008 /* You may use, modify, and distribute this software according */ 00009 /* to the terms stated in the LICENSE file included in */ 00010 /* the VIGRA distribution. */ 00011 /* */ 00012 /* The VIGRA Website is */ 00013 /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ 00014 /* Please direct questions, bug reports, and contributions to */ 00015 /* koethe@informatik.uni-hamburg.de */ 00016 /* */ 00017 /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ 00018 /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ 00019 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ 00020 /* */ 00021 /************************************************************************/ 00022 00023 #ifndef VIGRA_TIFF_HXX 00024 #define VIGRA_TIFF_HXX 00025 00026 #include "vigra/utilities.hxx" 00027 #include "vigra/numerictraits.hxx" 00028 #include "vigra/rgbvalue.hxx" 00029 extern "C" 00030 { 00031 #include <tiff.h> 00032 #include <tiffio.h> 00033 } 00034 00035 namespace vigra { 00036 00037 typedef TIFF TiffImage; 00038 00039 /** \defgroup TIFFImpex Import/export of the TIFF format 00040 00041 TIFF conversion and file export/import. 00042 00043 Normally, you need not call the TIFF functions directly. They are 00044 available much more conveniently via \ref importImage() and \ref exportImage() 00045 00046 TIFF (Tagged Image File Format) is a very versatile image format - 00047 one can store different pixel types (byte, integer, float, double) and 00048 color models (black and white, RGB, mapped RGB, other color systems). 00049 For more details and information on how to create a TIFF image, 00050 refer to the TIFF documentation at 00051 <a href="http://www.libtiff.org/">http://www.libtiff.org/</a> for details. 00052 */ 00053 //@{ 00054 00055 /********************************************************/ 00056 /* */ 00057 /* importTiffImage */ 00058 /* */ 00059 /********************************************************/ 00060 00061 /** \brief Convert given TiffImage into image specified by iterator range. 00062 00063 Accessors are used to write the data. 00064 This function calls \ref tiffToScalarImage() or \ref tiffToRGBImage(), depending on 00065 the accessor's value_type. 00066 00067 00068 <b> Declarations:</b> 00069 00070 pass arguments explicitly: 00071 \code 00072 namespace vigra { 00073 template <class ImageIterator, class Accessor> 00074 void 00075 importTiffImage(TiffImage * tiff, ImageIterator iter, Accessor a) 00076 } 00077 \endcode 00078 00079 use argument objects in conjunction with \ref ArgumentObjectFactories: 00080 \code 00081 namespace vigra { 00082 template <class ImageIterator, class Accessor> 00083 void 00084 importTiffImage(TiffImage * tiff, pair<ImageIterator, Accessor> dest) 00085 } 00086 \endcode 00087 00088 <b> Usage:</b> 00089 00090 <b>\#include</b> "<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>" 00091 00092 \code 00093 uint32 w, h; 00094 TiffImage * tiff = TIFFOpen("tiffimage.tiff", "r"); 00095 TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w); 00096 TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h); 00097 00098 vigra::BImage img(w,h); 00099 00100 vigra::importTiffImage(tiff, destImage(img)); 00101 00102 TIFFClose(tiff); 00103 \endcode 00104 00105 <b> Required Interface:</b> 00106 00107 see \ref tiffToScalarImage() and \ref tiffToRGBImage() 00108 00109 <b> Preconditions:</b> 00110 00111 see \ref tiffToScalarImage() and \ref tiffToRGBImage() 00112 00113 */ 00114 template <class ImageIterator, class Accessor> 00115 inline void 00116 importTiffImage(TiffImage * tiff, ImageIterator iter, Accessor a) 00117 { 00118 typedef typename 00119 NumericTraits<typename Accessor::value_type>::isScalar 00120 isScalar; 00121 importTiffImage(tiff, iter, a, isScalar()); 00122 } 00123 00124 template <class ImageIterator, class Accessor> 00125 inline void 00126 importTiffImage(TiffImage * tiff, pair<ImageIterator, Accessor> dest) 00127 { 00128 importTiffImage(tiff, dest.first, dest.second); 00129 } 00130 00131 template <class ImageIterator, class Accessor> 00132 inline void 00133 importTiffImage(TiffImage * tiff, ImageIterator iter, Accessor a, VigraTrueType) 00134 { 00135 tiffToScalarImage(tiff, iter, a); 00136 } 00137 00138 template <class ImageIterator, class Accessor> 00139 inline void 00140 importTiffImage(TiffImage * tiff, ImageIterator iter, Accessor a, VigraFalseType) 00141 { 00142 tiffToRGBImage(tiff, iter, a); 00143 } 00144 00145 /********************************************************/ 00146 /* */ 00147 /* tiffToScalarImage */ 00148 /* */ 00149 /********************************************************/ 00150 00151 /** \brief Convert single-band TiffImage to scalar image. 00152 00153 This function uses accessors to write the data. 00154 00155 <b> Declarations:</b> 00156 00157 pass arguments explicitly: 00158 \code 00159 namespace vigra { 00160 template <class ImageIterator, class Accessor> 00161 void 00162 tiffToScalarImage(TiffImage * tiff, ImageIterator iter, Accessor a) 00163 } 00164 \endcode 00165 00166 use argument objects in conjunction with \ref ArgumentObjectFactories: 00167 \code 00168 namespace vigra { 00169 template <class ImageIterator, class Accessor> 00170 void 00171 tiffToScalarImage(TiffImage * tiff, pair<ImageIterator, Accessor> dest) 00172 } 00173 \endcode 00174 00175 <b> Usage:</b> 00176 00177 <b>\#include</b> "<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>" 00178 00179 \code 00180 uint32 w, h; 00181 uint16 photometric 00182 TiffImage * tiff = TIFFOpen("tiffimage.tiff", "r"); 00183 TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w); 00184 TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h); 00185 TIFFGetField(tiff_, TIFFTAG_PHOTOMETRIC, &photometric); 00186 00187 if(photometric != PHOTOMETRIC_MINISWHITE && 00188 photometric != PHOTOMETRIC_MINISBLACK) 00189 { 00190 // not a scalar image - handle error 00191 } 00192 00193 vigra::BImage img(w,h); 00194 00195 vigra::tiffToScalarImage(tiff, destImage(img)); 00196 00197 TIFFClose(tiff); 00198 \endcode 00199 00200 <b> Required Interface:</b> 00201 00202 \code 00203 ImageIterator upperleft; 00204 <unsigned char, short, long, float, double> value; 00205 00206 Accessor accessor; 00207 00208 accessor.set(value, upperleft); 00209 \endcode 00210 00211 <b> Preconditions:</b> 00212 00213 ImageIterator must refer to a large enough image. 00214 00215 \code 00216 uint16 sampleFormat, samplesPerPixel, bitsPerSample, photometric; 00217 00218 TIFFGetField(tiff, TIFFTAG_SAMPLEFORMAT, &sampleFormat); 00219 TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel); 00220 TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitsPerSample); 00221 TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric); 00222 00223 sampleFormat != SAMPLEFORMAT_VOID 00224 samplesPerPixel == 1 00225 photometric == PHOTOMETRIC_MINISWHITE || 00226 photometric == PHOTOMETRIC_MINISBLACK 00227 bitsPerSample == 1 || 00228 bitsPerSample == 8 || 00229 bitsPerSample == 16 || 00230 bitsPerSample == 32 || 00231 bitsPerSample == 64 00232 00233 \endcode 00234 00235 */ 00236 template <class ImageIterator, class Accessor> 00237 void 00238 tiffToScalarImage(TiffImage * tiff, ImageIterator iter, Accessor a) 00239 { 00240 vigra_precondition(tiff != 0, 00241 "tiffToScalarImage(TiffImage *, ScalarImageIterator): " 00242 "NULL pointer to input data."); 00243 00244 uint16 sampleFormat = 1, bitsPerSample, 00245 fillorder, samplesPerPixel, photometric; 00246 uint32 w,h; 00247 00248 TIFFGetField(tiff, TIFFTAG_SAMPLEFORMAT, &sampleFormat); 00249 TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitsPerSample); 00250 TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel); 00251 TIFFGetField(tiff, TIFFTAG_FILLORDER, &fillorder); 00252 TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric); 00253 TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w); 00254 TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h); 00255 00256 vigra_precondition(photometric == PHOTOMETRIC_MINISWHITE || 00257 photometric == PHOTOMETRIC_MINISBLACK, 00258 "tiffToScalarImage(TiffImage *, ScalarImageIterator): " 00259 "Image isn't grayscale."); 00260 00261 vigra_precondition(samplesPerPixel == 1, 00262 "tiffToScalarImage(TiffImage *, ScalarImageIterator): " 00263 "Image is multiband, not scalar."); 00264 00265 vigra_precondition(sampleFormat != SAMPLEFORMAT_VOID, 00266 "tiffToScalarImage(TiffImage *, ScalarImageIterator): " 00267 "undefined pixeltype (SAMPLEFORMAT_VOID)."); 00268 00269 ImageIterator yd(iter); 00270 00271 int bufsize = TIFFScanlineSize(tiff); 00272 tdata_t * buf = new tdata_t[bufsize]; 00273 00274 int offset, scale, max, min; 00275 if(photometric == PHOTOMETRIC_MINISWHITE) 00276 { 00277 min = 255; 00278 max = 0; 00279 scale = -1; 00280 offset = 255; 00281 } 00282 else 00283 { 00284 scale = 1; 00285 offset = 0; 00286 min = 0; 00287 max = 255; 00288 } 00289 00290 try{ 00291 switch(sampleFormat) 00292 { 00293 case SAMPLEFORMAT_UINT: 00294 { 00295 switch (bitsPerSample) 00296 { 00297 case 1: 00298 { 00299 for(unsigned int y=0; y<h; ++y, ++yd.y) 00300 { 00301 TIFFReadScanline(tiff, buf, y); 00302 ImageIterator xd(yd); 00303 00304 for(unsigned int x=0; x<w; ++x, ++xd.x) 00305 { 00306 if(fillorder == FILLORDER_MSB2LSB) 00307 { 00308 a.set(((((uint8 *)buf)[x/8] >> (7 - x%8)) & 1) ? max : min, xd); 00309 } 00310 else 00311 { 00312 a.set(((((uint8 *)buf)[x/8] >> (x%8)) & 1) ? max : min, xd); 00313 } 00314 } 00315 } 00316 break; 00317 } 00318 case 8: 00319 { 00320 for(unsigned int y=0; y<h; ++y, ++yd.y) 00321 { 00322 TIFFReadScanline(tiff, buf, y); 00323 ImageIterator xd(yd); 00324 00325 for(unsigned int x=0; x<w; ++x, ++xd.x) 00326 { 00327 a.set(offset + scale*((uint8 *)buf)[x], xd); 00328 } 00329 } 00330 break; 00331 } 00332 case 16: 00333 { 00334 for(unsigned int y=0; y<h; ++y, ++yd.y) 00335 { 00336 TIFFReadScanline(tiff, buf, y); 00337 ImageIterator xd(yd); 00338 00339 for(unsigned int x=0; x<w; ++x, ++xd.x) 00340 { 00341 a.set(((uint16 *)buf)[x], xd); 00342 } 00343 } 00344 break; 00345 } 00346 case 32: 00347 { 00348 for(unsigned int y=0; y<h; ++y, ++yd.y) 00349 { 00350 TIFFReadScanline(tiff, buf, y); 00351 ImageIterator xd(yd); 00352 00353 for(unsigned int x=0; x<w; ++x, ++xd.x) 00354 { 00355 a.set(((uint32 *)buf)[x], xd); 00356 } 00357 } 00358 break; 00359 } 00360 default: 00361 vigra_fail("tiffToScalarImage(TiffImage *, ScalarImageIterator): " 00362 "unsupported number of bits per pixel"); 00363 } 00364 break; 00365 } 00366 case SAMPLEFORMAT_INT: 00367 { 00368 switch (bitsPerSample) 00369 { 00370 case 1: 00371 { 00372 for(unsigned int y=0; y<h; ++y, ++yd.y) 00373 { 00374 TIFFReadScanline(tiff, buf, y); 00375 ImageIterator xd(yd); 00376 00377 for(unsigned int x=0; x<w; ++x, ++xd.x) 00378 { 00379 if(fillorder == FILLORDER_MSB2LSB) 00380 { 00381 a.set(((((int8 *)buf)[x/8] >> (7 - x%8)) & 1) ? max : min, xd); 00382 } 00383 else 00384 { 00385 a.set(((((int8 *)buf)[x/8] >> (x%8)) & 1) ? max : min, xd); 00386 } 00387 } 00388 } 00389 break; 00390 } 00391 case 8: 00392 { 00393 for(unsigned int y=0; y<h; ++y, ++yd.y) 00394 { 00395 TIFFReadScanline(tiff, buf, y); 00396 ImageIterator xd(yd); 00397 00398 for(unsigned int x=0; x<w; ++x, ++xd.x) 00399 { 00400 a.set(offset + scale*((uint8 *)buf)[x], xd); 00401 } 00402 } 00403 break; 00404 } 00405 case 16: 00406 { 00407 for(unsigned int y=0; y<h; ++y, ++yd.y) 00408 { 00409 TIFFReadScanline(tiff, buf, y); 00410 ImageIterator xd(yd); 00411 00412 for(unsigned int x=0; x<w; ++x, ++xd.x) 00413 { 00414 a.set(((int16 *)buf)[x], xd); 00415 } 00416 } 00417 break; 00418 } 00419 case 32: 00420 { 00421 for(unsigned int y=0; y<h; ++y, ++yd.y) 00422 { 00423 TIFFReadScanline(tiff, buf, y); 00424 ImageIterator xd(yd); 00425 00426 for(unsigned int x=0; x<w; ++x, ++xd.x) 00427 { 00428 a.set(((int32 *)buf)[x], xd); 00429 } 00430 } 00431 break; 00432 } 00433 default: 00434 vigra_fail("tiffToScalarImage(TiffImage *, ScalarImageIterator): " 00435 "unsupported number of bits per pixel"); 00436 } 00437 break; 00438 } 00439 case SAMPLEFORMAT_IEEEFP: 00440 { 00441 switch (bitsPerSample) 00442 { 00443 case sizeof(float)*8: 00444 { 00445 for(unsigned int y=0; y<h; ++y, ++yd.y) 00446 { 00447 TIFFReadScanline(tiff, buf, y); 00448 ImageIterator xd(yd); 00449 00450 for(unsigned int x=0; x<w; ++x, ++xd.x) 00451 { 00452 a.set(((float *)buf)[x], xd); 00453 } 00454 } 00455 break; 00456 } 00457 case sizeof(double)*8: 00458 { 00459 for(unsigned int y=0; y<h; ++y, ++yd.y) 00460 { 00461 TIFFReadScanline(tiff, buf, y); 00462 ImageIterator xd(yd); 00463 00464 for(unsigned int x=0; x<w; ++x, ++xd.x) 00465 { 00466 a.set(((double *)buf)[x], xd); 00467 } 00468 } 00469 break; 00470 } 00471 default: 00472 vigra_fail("tiffToScalarImage(TiffImage *, ScalarImageIterator): " 00473 "unsupported number of bits per pixel"); 00474 } 00475 break; 00476 } 00477 default: 00478 { 00479 // should never happen 00480 vigra_fail("tiffToScalarImage(TiffImage *, ScalarImageIterator): " 00481 "internal error."); 00482 } 00483 } 00484 } 00485 catch(...) 00486 { 00487 delete[] buf; 00488 throw; 00489 } 00490 delete[] buf; 00491 } 00492 00493 template <class ImageIterator, class Accessor> 00494 void 00495 tiffToScalarImage(TiffImage * tiff, pair<ImageIterator, Accessor> dest) 00496 { 00497 tiffToScalarImage(tiff, dest.first, dest.second); 00498 } 00499 00500 /********************************************************/ 00501 /* */ 00502 /* tiffToRGBImage */ 00503 /* */ 00504 /********************************************************/ 00505 00506 /** \brief Convert RGB (3-band or color-mapped) TiffImage 00507 to RGB image. 00508 00509 This function uses \ref RGBAccessor to write the data. 00510 A RGBImageIterator is an iterator which is associated with a 00511 RGBAccessor. 00512 00513 <b> Declarations:</b> 00514 00515 pass arguments explicitly: 00516 \code 00517 namespace vigra { 00518 template <class RGBImageIterator, class RGBAccessor> 00519 void 00520 tiffToRGBImage(TiffImage * tiff, RGBImageIterator iter, RGBAccessor a) 00521 } 00522 \endcode 00523 00524 use argument objects in conjunction with \ref ArgumentObjectFactories: 00525 \code 00526 namespace vigra { 00527 template <class RGBImageIterator, class RGBAccessor> 00528 void 00529 tiffToRGBImage(TiffImage * tiff, pair<RGBImageIterator, RGBAccessor> dest) 00530 } 00531 \endcode 00532 00533 <b> Usage:</b> 00534 00535 <b>\#include</b> "<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>" 00536 00537 \code 00538 uint32 w, h; 00539 uint16 photometric 00540 TiffImage * tiff = TIFFOpen("tiffimage.tiff", "r"); 00541 TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w); 00542 TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h); 00543 TIFFGetField(tiff_, TIFFTAG_PHOTOMETRIC, &photometric); 00544 00545 if(photometric != PHOTOMETRIC_RGB && 00546 photometric != PHOTOMETRIC_PALETTE) 00547 { 00548 // not an RGB image - handle error 00549 } 00550 00551 vigra::BRGBImage img(w, h); 00552 00553 vigra::tiffToRGBImage(tiff, destImage(img)); 00554 00555 TIFFClose(tiff); 00556 \endcode 00557 00558 <b> Required Interface:</b> 00559 00560 \code 00561 ImageIterator upperleft; 00562 <unsigned char, short, long, float, double> rvalue, gvalue, bvalue; 00563 00564 RGBAccessor accessor; 00565 00566 accessor.setRed(rvalue, upperleft); 00567 accessor.setGreen(gvalue, upperleft); 00568 accessor.setBlue(bvalue, upperleft); 00569 \endcode 00570 00571 <b> Preconditions:</b> 00572 00573 ImageIterator must refer to a large enough image. 00574 00575 \code 00576 uint16 sampleFormat, samplesPerPixel, bitsPerSample, photometric; 00577 00578 TIFFGetField(tiff, TIFFTAG_SAMPLEFORMAT, &sampleFormat); 00579 TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel); 00580 TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitsPerSample); 00581 TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric); 00582 00583 sampleFormat != SAMPLEFORMAT_VOID 00584 samplesPerPixel == 3 // unlass photometric == PHOTOMETRIC_PALETTE 00585 photometric == PHOTOMETRIC_RGB || 00586 photometric == PHOTOMETRIC_PALETTE 00587 bitsPerSample == 1 || 00588 bitsPerSample == 8 || 00589 bitsPerSample == 16 || 00590 bitsPerSample == 32 || 00591 bitsPerSample == 64 00592 \endcode 00593 00594 */ 00595 template <class RGBImageIterator, class RGBAccessor> 00596 void 00597 tiffToRGBImage(TiffImage * tiff, RGBImageIterator iter, RGBAccessor a) 00598 { 00599 vigra_precondition(tiff != 0, 00600 "tiffToRGBImage(TiffImage *, RGBImageIterator): " 00601 "NULL pointer to input data."); 00602 00603 uint16 sampleFormat = 1, bitsPerSample, 00604 samplesPerPixel, planarConfig, photometric; 00605 uint32 w,h; 00606 00607 TIFFGetField(tiff, TIFFTAG_SAMPLEFORMAT, &sampleFormat); 00608 TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitsPerSample); 00609 TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel); 00610 TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric); 00611 TIFFGetField(tiff, TIFFTAG_PLANARCONFIG, &planarConfig); 00612 TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w); 00613 TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h); 00614 00615 vigra_precondition(photometric == PHOTOMETRIC_RGB || 00616 photometric == PHOTOMETRIC_PALETTE, 00617 "tiffToRGBImage(TiffImage *, RGBImageIterator): " 00618 "Image isn't RGB."); 00619 00620 vigra_precondition(sampleFormat != SAMPLEFORMAT_VOID, 00621 "tiffToRGBImage(TiffImage *, RGBImageIterator): " 00622 "undefined pixeltype (SAMPLEFORMAT_VOID)."); 00623 00624 RGBImageIterator yd(iter); 00625 00626 switch (photometric) 00627 { 00628 case PHOTOMETRIC_PALETTE: 00629 { 00630 uint32 * raster = new uint32[w*h]; 00631 try 00632 { 00633 if (!TIFFReadRGBAImage(tiff, w, h, raster, 0)) 00634 { 00635 vigra_fail( 00636 "tiffToRGBImage(TiffImage *, RGBImageIterator): " 00637 "unable to read image data."); 00638 } 00639 00640 for(unsigned int y=0; y<h; ++y, ++yd.y) 00641 { 00642 typename RGBImageIterator::row_iterator rowit = yd.rowIterator(); 00643 typename RGBImageIterator::row_iterator rowend = rowit + w; 00644 for(int x=0; rowit<rowend; ++rowit,++x ) 00645 { 00646 uint32 rast = raster[x+y*w]; 00647 a.setRGB(TIFFGetR(rast),TIFFGetG(rast),TIFFGetB(rast),rowit); 00648 } 00649 } 00650 } 00651 catch(...) 00652 { 00653 delete[] raster; 00654 throw; 00655 } 00656 delete[] raster; 00657 break; 00658 } 00659 case PHOTOMETRIC_RGB: 00660 { 00661 vigra_precondition(samplesPerPixel == 3, 00662 "tiffToRGBImage(TiffImage *, RGBImageIterator): " 00663 "number of samples per pixel must be 3."); 00664 00665 int bufsize = TIFFScanlineSize(tiff); 00666 tdata_t * bufr = new tdata_t[bufsize]; 00667 tdata_t * bufg = new tdata_t[bufsize]; 00668 tdata_t * bufb = new tdata_t[bufsize]; 00669 00670 int offset = (planarConfig == PLANARCONFIG_CONTIG) ? 3 : 1; 00671 00672 try 00673 { 00674 switch(sampleFormat) 00675 { 00676 case SAMPLEFORMAT_UINT: 00677 { 00678 switch (bitsPerSample) 00679 { 00680 case 8: 00681 { 00682 for(unsigned int y=0; y<h; ++y, ++yd.y) 00683 { 00684 uint8 *pr, *pg, *pb; 00685 00686 if(planarConfig == PLANARCONFIG_CONTIG) 00687 { 00688 TIFFReadScanline(tiff, bufr, y); 00689 pr = (uint8 *)bufr; 00690 pg = pr+1; 00691 pb = pg+1; 00692 } 00693 else 00694 { 00695 TIFFReadScanline(tiff, bufr, y, 0); 00696 TIFFReadScanline(tiff, bufg, y, 1); 00697 TIFFReadScanline(tiff, bufb, y, 2); 00698 pr = (uint8 *)bufr; 00699 pg = (uint8 *)bufg; 00700 pb = (uint8 *)bufb; 00701 } 00702 00703 typename RGBImageIterator::row_iterator rowit = yd.rowIterator(); 00704 typename RGBImageIterator::row_iterator rowend = rowit + w; 00705 for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset) 00706 a.setRGB(*pr,*pg, *pb, rowit); 00707 } 00708 break; 00709 } 00710 case 16: 00711 { 00712 for(unsigned int y=0; y<h; ++y, ++yd.y) 00713 { 00714 uint16 *pr, *pg, *pb; 00715 00716 if(planarConfig == PLANARCONFIG_CONTIG) 00717 { 00718 TIFFReadScanline(tiff, bufr, y); 00719 pr = (uint16 *)bufr; 00720 pg = pr+1; 00721 pb = pg+1; 00722 } 00723 else 00724 { 00725 TIFFReadScanline(tiff, bufr, y, 0); 00726 TIFFReadScanline(tiff, bufg, y, 1); 00727 TIFFReadScanline(tiff, bufb, y, 2); 00728 pr = (uint16 *)bufr; 00729 pg = (uint16 *)bufg; 00730 pb = (uint16 *)bufb; 00731 } 00732 00733 typename RGBImageIterator::row_iterator rowit = yd.rowIterator(); 00734 typename RGBImageIterator::row_iterator rowend = rowit + w; 00735 for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset) 00736 a.setRGB(*pr,*pg, *pb, rowit); 00737 } 00738 break; 00739 } 00740 case 32: 00741 { 00742 for(unsigned int y=0; y<h; ++y, ++yd.y) 00743 { 00744 uint32 *pr, *pg, *pb; 00745 00746 if(planarConfig == PLANARCONFIG_CONTIG) 00747 { 00748 TIFFReadScanline(tiff, bufr, y); 00749 pr = (uint32 *)bufr; 00750 pg = pr+1; 00751 pb = pg+1; 00752 } 00753 else 00754 { 00755 TIFFReadScanline(tiff, bufr, y, 0); 00756 TIFFReadScanline(tiff, bufg, y, 1); 00757 TIFFReadScanline(tiff, bufb, y, 2); 00758 pr = (uint32 *)bufr; 00759 pg = (uint32 *)bufg; 00760 pb = (uint32 *)bufb; 00761 } 00762 00763 typename RGBImageIterator::row_iterator rowit = yd.rowIterator(); 00764 typename RGBImageIterator::row_iterator rowend = rowit + w; 00765 for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset) 00766 a.setRGB(*pr,*pg, *pb, rowit); 00767 } 00768 break; 00769 } 00770 default: 00771 { 00772 vigra_fail("tiffToRGBImage(TiffImage *, RGBImageIterator): " 00773 "unsupported number of bits per pixel"); 00774 } 00775 } 00776 break; 00777 } 00778 case SAMPLEFORMAT_INT: 00779 { 00780 switch (bitsPerSample) 00781 { 00782 case 8: 00783 { 00784 for(unsigned int y=0; y<h; ++y, ++yd.y) 00785 { 00786 int8 *pr, *pg, *pb; 00787 00788 if(planarConfig == PLANARCONFIG_CONTIG) 00789 { 00790 TIFFReadScanline(tiff, bufr, y); 00791 pr = (int8 *)bufr; 00792 pg = pr+1; 00793 pb = pg+1; 00794 } 00795 else 00796 { 00797 TIFFReadScanline(tiff, bufr, y, 0); 00798 TIFFReadScanline(tiff, bufg, y, 1); 00799 TIFFReadScanline(tiff, bufb, y, 2); 00800 pr = (int8 *)bufr; 00801 pg = (int8 *)bufg; 00802 pb = (int8 *)bufb; 00803 } 00804 00805 typename RGBImageIterator::row_iterator rowit = yd.rowIterator(); 00806 typename RGBImageIterator::row_iterator rowend = rowit + w; 00807 for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset) 00808 a.setRGB(*pr,*pg, *pb, rowit); 00809 } 00810 break; 00811 } 00812 case 16: 00813 { 00814 for(unsigned int y=0; y<h; ++y, ++yd.y) 00815 { 00816 int16 *pr, *pg, *pb; 00817 00818 if(planarConfig == PLANARCONFIG_CONTIG) 00819 { 00820 TIFFReadScanline(tiff, bufr, y); 00821 pr = (int16 *)bufr; 00822 pg = pr+1; 00823 pb = pg+1; 00824 } 00825 else 00826 { 00827 TIFFReadScanline(tiff, bufr, y, 0); 00828 TIFFReadScanline(tiff, bufg, y, 1); 00829 TIFFReadScanline(tiff, bufb, y, 2); 00830 pr = (int16 *)bufr; 00831 pg = (int16 *)bufg; 00832 pb = (int16 *)bufb; 00833 } 00834 typename RGBImageIterator::row_iterator rowit = yd.rowIterator(); 00835 typename RGBImageIterator::row_iterator rowend = rowit + w; 00836 for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset) 00837 a.setRGB(*pr,*pg, *pb, rowit); 00838 } 00839 break; 00840 } 00841 case 32: 00842 { 00843 for(unsigned int y=0; y<h; ++y, ++yd.y) 00844 { 00845 int32 *pr, *pg, *pb; 00846 00847 if(planarConfig == PLANARCONFIG_CONTIG) 00848 { 00849 TIFFReadScanline(tiff, bufr, y); 00850 pr = (int32 *)bufr; 00851 pg = pr+1; 00852 pb = pg+1; 00853 } 00854 else 00855 { 00856 TIFFReadScanline(tiff, bufr, y, 0); 00857 TIFFReadScanline(tiff, bufg, y, 1); 00858 TIFFReadScanline(tiff, bufb, y, 2); 00859 pr = (int32 *)bufr; 00860 pg = (int32 *)bufg; 00861 pb = (int32 *)bufb; 00862 } 00863 00864 typename RGBImageIterator::row_iterator rowit = yd.rowIterator(); 00865 typename RGBImageIterator::row_iterator rowend = rowit + w; 00866 for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset) 00867 a.setRGB(*pr,*pg, *pb, rowit); 00868 } 00869 break; 00870 } 00871 default: 00872 vigra_fail("tiffToRGBImage(TiffImage *, RGBImageIterator): " 00873 "unsupported number of bits per pixel"); 00874 } 00875 break; 00876 } 00877 case SAMPLEFORMAT_IEEEFP: 00878 { 00879 switch (bitsPerSample) 00880 { 00881 case sizeof(float)*8: 00882 { 00883 for(unsigned int y=0; y<h; ++y, ++yd.y) 00884 { 00885 float *pr, *pg, *pb; 00886 00887 if(planarConfig == PLANARCONFIG_CONTIG) 00888 { 00889 TIFFReadScanline(tiff, bufr, y); 00890 pr = (float *)bufr; 00891 pg = pr+1; 00892 pb = pg+1; 00893 } 00894 else 00895 { 00896 TIFFReadScanline(tiff, bufr, y, 0); 00897 TIFFReadScanline(tiff, bufg, y, 1); 00898 TIFFReadScanline(tiff, bufb, y, 2); 00899 pr = (float *)bufr; 00900 pg = (float *)bufg; 00901 pb = (float *)bufb; 00902 } 00903 00904 typename RGBImageIterator::row_iterator rowit = yd.rowIterator(); 00905 typename RGBImageIterator::row_iterator rowend = rowit + w; 00906 for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset) 00907 a.setRGB(*pr,*pg, *pb, rowit); 00908 } 00909 break; 00910 } 00911 case sizeof(double)*8: 00912 { 00913 for(unsigned int y=0; y<h; ++y, ++yd.y) 00914 { 00915 double *pr, *pg, *pb; 00916 00917 if(planarConfig == PLANARCONFIG_CONTIG) 00918 { 00919 TIFFReadScanline(tiff, bufr, y); 00920 pr = (double *)bufr; 00921 pg = pr+1; 00922 pb = pg+1; 00923 } 00924 else 00925 { 00926 TIFFReadScanline(tiff, bufr, y, 0); 00927 TIFFReadScanline(tiff, bufg, y, 1); 00928 TIFFReadScanline(tiff, bufb, y, 2); 00929 pr = (double *)bufr; 00930 pg = (double *)bufg; 00931 pb = (double *)bufb; 00932 } 00933 00934 typename RGBImageIterator::row_iterator rowit = yd.rowIterator(); 00935 typename RGBImageIterator::row_iterator rowend = rowit + w; 00936 for(; rowit<rowend; ++rowit, pr+=offset, pg+=offset, pb+=offset) 00937 a.setRGB(*pr,*pg, *pb, rowit); 00938 } 00939 break; 00940 } 00941 default: 00942 vigra_fail("tiffToRGBImage(TiffImage *, RGBImageIterator): " 00943 "unsupported number of bits per pixel"); 00944 } 00945 break; 00946 } 00947 default: 00948 { 00949 // should never happen 00950 vigra_fail("tiffToRGBImage(TiffImage *, RGBImageIterator): " 00951 "internal error."); 00952 } 00953 } 00954 } 00955 catch(...) 00956 { 00957 delete[] bufr; 00958 delete[] bufg; 00959 delete[] bufb; 00960 throw; 00961 } 00962 delete[] bufr; 00963 delete[] bufg; 00964 delete[] bufb; 00965 00966 break; 00967 } 00968 default: 00969 { 00970 // should never happen 00971 vigra_fail( 00972 "tiffToRGBImage(TiffImage *, RGBImageIterator): " 00973 "internal error."); 00974 } 00975 } 00976 } 00977 00978 template <class ImageIterator, class VectorComponentAccessor> 00979 void 00980 tiffToRGBImage(TiffImage * tiff, pair<ImageIterator, VectorComponentAccessor> dest) 00981 { 00982 tiffToRGBImage(tiff, dest.first, dest.second); 00983 } 00984 00985 template <class T> 00986 struct CreateTiffImage; 00987 00988 /********************************************************/ 00989 /* */ 00990 /* createTiffImage */ 00991 /* */ 00992 /********************************************************/ 00993 00994 /** \brief Create a TiffImage from the given iterator range. 00995 00996 Type and size of the TiffImage are determined by the input image. 00997 Currently, the function can create scalar images and RGB images of type 00998 unsigned char, short, int, float, and double. 00999 This function uses accessors to read the data. 01000 01001 <b> Declarations:</b> 01002 01003 pass arguments explicitly: 01004 \code 01005 namespace vigra { 01006 template <class ImageIterator, class Accessor> 01007 inline TiffImage * 01008 createTiffImage(ImageIterator upperleft, ImageIterator lowerright, 01009 Accessor a) 01010 } 01011 \endcode 01012 01013 use argument objects in conjunction with \ref ArgumentObjectFactories: 01014 \code 01015 namespace vigra { 01016 template <class ImageIterator, class Accessor> 01017 inline TiffImage * 01018 createTiffImage(triple<ImageIterator, ImageIterator, Accessor> src) 01019 } 01020 \endcode 01021 01022 <b> Usage:</b> 01023 01024 <b>\#include</b> "<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>" 01025 01026 \code 01027 vigra::BImage img(width, height); 01028 01029 ... 01030 01031 TiffImage * tiff = TIFFOpen(("tiffimage.tiff", "w"); 01032 01033 vigra::createTiffImage(srcImageRange(img), tiff); 01034 01035 TIFFClose(tiff); // implicitly writes the image to the disk 01036 \endcode 01037 01038 <b> Required Interface:</b> 01039 01040 \code 01041 ImageIterator upperleft; 01042 Accessor accessor; 01043 01044 accessor(upperleft); // result written into TiffImage 01045 \endcode 01046 01047 */ 01048 template <class ImageIterator, class Accessor> 01049 inline void 01050 createTiffImage(ImageIterator upperleft, ImageIterator lowerright, 01051 Accessor a, TiffImage * tiff) 01052 { 01053 CreateTiffImage<typename Accessor::value_type>:: 01054 exec(upperleft, lowerright, a, tiff); 01055 } 01056 01057 template <class ImageIterator, class Accessor> 01058 inline void 01059 createTiffImage(triple<ImageIterator, ImageIterator, Accessor> src, TiffImage * tiff) 01060 { 01061 createTiffImage(src.first, src.second, src.third, tiff); 01062 } 01063 01064 /********************************************************/ 01065 /* */ 01066 /* createScalarTiffImage */ 01067 /* */ 01068 /********************************************************/ 01069 01070 /** \brief Create a single-band TiffImage from the given scalar image. 01071 01072 Type and size of the TiffImage are determined by the input image 01073 (may be one of unsigned char, short, int, float, or double). 01074 This function uses accessors to read the data. 01075 01076 <b> Declarations:</b> 01077 01078 pass arguments explicitly: 01079 \code 01080 namespace vigra { 01081 template <class ImageIterator, class Accessor> 01082 inline TiffImage * 01083 createScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 01084 Accessor a) 01085 } 01086 \endcode 01087 01088 use argument objects in conjunction with \ref ArgumentObjectFactories: 01089 \code 01090 namespace vigra { 01091 template <class ImageIterator, class Accessor> 01092 inline TiffImage * 01093 createScalarTiffImage(triple<ImageIterator, ImageIterator, Accessor> src) 01094 } 01095 \endcode 01096 01097 <b> Usage:</b> 01098 01099 <b>\#include</b> "<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>" 01100 01101 \code 01102 vigra::BImage img(width, height); 01103 01104 ... 01105 01106 TiffImage * tiff = TIFFOpen(("tiffimage.tiff", "w"); 01107 01108 vigra::createScalarTiffImage(srcImageRange(img), tiff); 01109 01110 TIFFClose(tiff); // implicitly writes the image to the disk 01111 \endcode 01112 01113 <b> Required Interface:</b> 01114 01115 \code 01116 ImageIterator upperleft; 01117 Accessor accessor; 01118 01119 accessor(upperleft); // result written into TiffImage 01120 \endcode 01121 01122 */ 01123 template <class ImageIterator, class Accessor> 01124 inline void 01125 createScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 01126 Accessor a, TiffImage * tiff) 01127 { 01128 CreateTiffImage<typename Accessor::value_type>:: 01129 exec(upperleft, lowerright, a, tiff); 01130 } 01131 01132 template <class ImageIterator, class Accessor> 01133 inline void 01134 createScalarTiffImage(triple<ImageIterator, ImageIterator, Accessor> src, TiffImage * tiff) 01135 { 01136 createScalarTiffImage(src.first, src.second, src.third, tiff); 01137 } 01138 01139 template <class ImageIterator, class Accessor> 01140 void 01141 createBScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 01142 Accessor a, TiffImage * tiff) 01143 { 01144 int w = lowerright.x - upperleft.x; 01145 int h = lowerright.y - upperleft.y; 01146 01147 TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w); 01148 TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h); 01149 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8); 01150 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1); 01151 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); 01152 TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); 01153 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); 01154 01155 int bufsize = TIFFScanlineSize(tiff); 01156 tdata_t * buf = new tdata_t[bufsize]; 01157 01158 ImageIterator ys(upperleft); 01159 01160 try 01161 { 01162 for(int y=0; y<h; ++y, ++ys.y) 01163 { 01164 uint8 * p = (uint8 *)buf; 01165 ImageIterator xs(ys); 01166 01167 for(int x=0; x<w; ++x, ++xs.x) 01168 { 01169 p[x] = a(xs); 01170 } 01171 TIFFWriteScanline(tiff, buf, y); 01172 } 01173 } 01174 catch(...) 01175 { 01176 delete[] buf; 01177 throw; 01178 } 01179 delete[] buf; 01180 } 01181 01182 template <class ImageIterator, class Accessor> 01183 void 01184 createShortScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 01185 Accessor a, TiffImage * tiff) 01186 { 01187 int w = lowerright.x - upperleft.x; 01188 int h = lowerright.y - upperleft.y; 01189 01190 TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w); 01191 TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h); 01192 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 16); 01193 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1); 01194 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); 01195 TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); 01196 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); 01197 01198 int bufsize = TIFFScanlineSize(tiff); 01199 tdata_t * buf = new tdata_t[bufsize]; 01200 01201 ImageIterator ys(upperleft); 01202 01203 try 01204 { 01205 for(int y=0; y<h; ++y, ++ys.y) 01206 { 01207 int16 * p = (int16 *)buf; 01208 ImageIterator xs(ys); 01209 01210 for(int x=0; x<w; ++x, ++xs.x) 01211 { 01212 p[x] = a(xs); 01213 } 01214 TIFFWriteScanline(tiff, buf, y); 01215 } 01216 } 01217 catch(...) 01218 { 01219 delete[] buf; 01220 throw; 01221 } 01222 delete[] buf; 01223 } 01224 01225 template <class ImageIterator, class Accessor> 01226 void 01227 createIScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 01228 Accessor a, TiffImage * tiff) 01229 { 01230 int w = lowerright.x - upperleft.x; 01231 int h = lowerright.y - upperleft.y; 01232 01233 TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w); 01234 TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h); 01235 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 32); 01236 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1); 01237 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); 01238 TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); 01239 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); 01240 01241 int bufsize = TIFFScanlineSize(tiff); 01242 tdata_t * buf = new tdata_t[bufsize]; 01243 01244 ImageIterator ys(upperleft); 01245 01246 try 01247 { 01248 for(int y=0; y<h; ++y, ++ys.y) 01249 { 01250 int32 * p = (int32 *)buf; 01251 ImageIterator xs(ys); 01252 01253 for(int x=0; x<w; ++x, ++xs.x) 01254 { 01255 p[x] = a(xs); 01256 } 01257 TIFFWriteScanline(tiff, buf, y); 01258 } 01259 } 01260 catch(...) 01261 { 01262 delete[] buf; 01263 throw; 01264 } 01265 delete[] buf; 01266 } 01267 01268 template <class ImageIterator, class Accessor> 01269 void 01270 createFScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 01271 Accessor a, TiffImage * tiff) 01272 { 01273 int w = lowerright.x - upperleft.x; 01274 int h = lowerright.y - upperleft.y; 01275 01276 TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w); 01277 TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h); 01278 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, sizeof(float)*8); 01279 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1); 01280 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); 01281 TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); 01282 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); 01283 01284 int bufsize = TIFFScanlineSize(tiff); 01285 tdata_t * buf = new tdata_t[bufsize]; 01286 01287 ImageIterator ys(upperleft); 01288 01289 try 01290 { 01291 for(int y=0; y<h; ++y, ++ys.y) 01292 { 01293 float * p = (float *)buf; 01294 ImageIterator xs(ys); 01295 01296 for(int x=0; x<w; ++x, ++xs.x) 01297 { 01298 p[x] = a(xs); 01299 } 01300 TIFFWriteScanline(tiff, buf, y); 01301 } 01302 } 01303 catch(...) 01304 { 01305 delete[] buf; 01306 throw; 01307 } 01308 delete[] buf; 01309 } 01310 01311 template <class ImageIterator, class Accessor> 01312 void 01313 createDScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, 01314 Accessor a, TiffImage * tiff) 01315 { 01316 int w = lowerright.x - upperleft.x; 01317 int h = lowerright.y - upperleft.y; 01318 01319 TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w); 01320 TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h); 01321 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, sizeof(double)*8); 01322 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1); 01323 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); 01324 TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); 01325 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); 01326 01327 int bufsize = TIFFScanlineSize(tiff); 01328 tdata_t * buf = new tdata_t[bufsize]; 01329 01330 ImageIterator ys(upperleft); 01331 01332 try 01333 { 01334 for(int y=0; y<h; ++y, ++ys.y) 01335 { 01336 double * p = (double *)buf; 01337 ImageIterator xs(ys); 01338 01339 for(int x=0; x<w; ++x, ++xs.x) 01340 { 01341 p[x] = a(xs); 01342 } 01343 TIFFWriteScanline(tiff, buf, y); 01344 } 01345 } 01346 catch(...) 01347 { 01348 delete[] buf; 01349 throw; 01350 } 01351 delete[] buf; 01352 } 01353 01354 template <> 01355 struct CreateTiffImage<unsigned char> 01356 { 01357 template <class ImageIterator, class Accessor> 01358 static void 01359 exec(ImageIterator upperleft, ImageIterator lowerright, 01360 Accessor a, TiffImage * tiff) 01361 { 01362 createBScalarTiffImage(upperleft, lowerright, a, tiff); 01363 } 01364 }; 01365 01366 template <> 01367 struct CreateTiffImage<short> 01368 { 01369 template <class ImageIterator, class Accessor> 01370 static void 01371 exec(ImageIterator upperleft, ImageIterator lowerright, 01372 Accessor a, TiffImage * tiff) 01373 { 01374 createShortScalarTiffImage(upperleft, lowerright, a, tiff); 01375 } 01376 }; 01377 01378 template <> 01379 struct CreateTiffImage<int> 01380 { 01381 template <class ImageIterator, class Accessor> 01382 static void 01383 exec(ImageIterator upperleft, ImageIterator lowerright, 01384 Accessor a, TiffImage * tiff) 01385 { 01386 createIScalarTiffImage(upperleft, lowerright, a, tiff); 01387 } 01388 }; 01389 01390 template <> 01391 struct CreateTiffImage<float> 01392 { 01393 template <class ImageIterator, class Accessor> 01394 static void 01395 exec(ImageIterator upperleft, ImageIterator lowerright, 01396 Accessor a, TiffImage * tiff) 01397 { 01398 createFScalarTiffImage(upperleft, lowerright, a, tiff); 01399 } 01400 }; 01401 01402 template <> 01403 struct CreateTiffImage<double> 01404 { 01405 template <class ImageIterator, class Accessor> 01406 static void 01407 exec(ImageIterator upperleft, ImageIterator lowerright, 01408 Accessor a, TiffImage * tiff) 01409 { 01410 createDScalarTiffImage(upperleft, lowerright, a, tiff); 01411 } 01412 }; 01413 01414 /********************************************************/ 01415 /* */ 01416 /* createRGBTiffImage */ 01417 /* */ 01418 /********************************************************/ 01419 01420 /** \brief Create a 3-band TiffImage from the given RGB image. 01421 01422 Type and size of the TiffImage are determined by the input image 01423 (may be one of unsigned char, int, float, or double). 01424 This function uses \ref RGBAccessor to read the data. A 01425 RGBImageIterator is an iterator that is associated with a 01426 RGBAccessor. 01427 01428 <b> Declarations:</b> 01429 01430 pass arguments explicitly: 01431 \code 01432 namespace vigra { 01433 template <class RGBImageIterator, class RGBAccessor> 01434 TiffImage * 01435 createRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright, 01436 RGBAccessor a) 01437 } 01438 \endcode 01439 01440 use argument objects in conjunction with \ref ArgumentObjectFactories: 01441 \code 01442 namespace vigra { 01443 template <class RGBImageIterator, class RGBAccessor> 01444 inline TiffImage * 01445 createRGBTiffImage(triple<RGBImageIterator, RGBImageIterator, RGBAccessor> src) 01446 } 01447 \endcode 01448 01449 <b> Usage:</b> 01450 01451 <b>\#include</b> "<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>" 01452 01453 \code 01454 vigra::BRGBImage img(width, height); 01455 01456 ... 01457 01458 TiffImage * tiff = TIFFOpen(("tiffimage.tiff", "w"); 01459 01460 vigra::createRGBTiffImage(srcImageRange(img), tiff); 01461 01462 TIFFClose(tiff); // implicitly writes the image to the disk 01463 \endcode 01464 01465 <b> Required Interface:</b> 01466 01467 \code 01468 ImageIterator upperleft; 01469 RGBAccessor accessor; 01470 01471 accessor.red(upperleft); // result written into TiffImage 01472 accessor.green(upperleft); // result written into TiffImage 01473 accessor.blue(upperleft); // result written into TiffImage 01474 \endcode 01475 01476 */ 01477 template <class RGBImageIterator, class RGBAccessor> 01478 inline void 01479 createRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright, 01480 RGBAccessor a, TiffImage * tiff) 01481 { 01482 CreateTiffImage<typename RGBAccessor::value_type>:: 01483 exec(upperleft, lowerright, a, tiff); 01484 } 01485 01486 template <class RGBImageIterator, class RGBAccessor> 01487 inline void 01488 createRGBTiffImage(triple<RGBImageIterator, RGBImageIterator, RGBAccessor> src, TiffImage * tiff) 01489 { 01490 createRGBTiffImage(src.first, src.second, src.third, tiff); 01491 } 01492 01493 template <class RGBImageIterator, class RGBAccessor> 01494 void 01495 createBRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright, 01496 RGBAccessor a, TiffImage * tiff) 01497 { 01498 int w = lowerright.x - upperleft.x; 01499 int h = lowerright.y - upperleft.y; 01500 01501 TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w); 01502 TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h); 01503 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8); 01504 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3); 01505 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); 01506 TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); 01507 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); 01508 01509 int bufsize = TIFFScanlineSize(tiff); 01510 tdata_t * buf = new tdata_t[bufsize]; 01511 01512 RGBImageIterator ys(upperleft); 01513 01514 try 01515 { 01516 for(int y=0; y<h; ++y, ++ys.y) 01517 { 01518 uint8 * pr = (uint8 *)buf; 01519 uint8 * pg = pr+1; 01520 uint8 * pb = pg+1; 01521 01522 RGBImageIterator xs(ys); 01523 01524 for(int x=0; x<w; ++x, ++xs.x, pr+=3, pg+=3, pb+=3) 01525 { 01526 *pr = a.red(xs); 01527 *pg = a.green(xs); 01528 *pb = a.blue(xs); 01529 } 01530 TIFFWriteScanline(tiff, buf, y); 01531 } 01532 } 01533 catch(...) 01534 { 01535 delete[] buf; 01536 throw; 01537 } 01538 delete[] buf; 01539 } 01540 01541 template <class RGBImageIterator, class RGBAccessor> 01542 void 01543 createShortRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright, 01544 RGBAccessor a, TiffImage * tiff) 01545 { 01546 int w = lowerright.x - upperleft.x; 01547 int h = lowerright.y - upperleft.y; 01548 01549 TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w); 01550 TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h); 01551 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 16); 01552 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3); 01553 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); 01554 TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); 01555 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); 01556 01557 int bufsize = TIFFScanlineSize(tiff); 01558 tdata_t * buf = new tdata_t[bufsize]; 01559 01560 RGBImageIterator ys(upperleft); 01561 01562 try 01563 { 01564 for(int y=0; y<h; ++y, ++ys.y) 01565 { 01566 uint16 * pr = (uint16 *)buf; 01567 uint16 * pg = pr+1; 01568 uint16 * pb = pg+1; 01569 01570 RGBImageIterator xs(ys); 01571 01572 for(int x=0; x<w; ++x, ++xs.x, pr+=3, pg+=3, pb+=3) 01573 { 01574 *pr = a.red(xs); 01575 *pg = a.green(xs); 01576 *pb = a.blue(xs); 01577 } 01578 TIFFWriteScanline(tiff, buf, y); 01579 } 01580 } 01581 catch(...) 01582 { 01583 delete[] buf; 01584 throw; 01585 } 01586 delete[] buf; 01587 } 01588 01589 template <class RGBImageIterator, class RGBAccessor> 01590 void 01591 createIRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright, 01592 RGBAccessor a, TiffImage * tiff) 01593 { 01594 int w = lowerright.x - upperleft.x; 01595 int h = lowerright.y - upperleft.y; 01596 01597 TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w); 01598 TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h); 01599 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 32); 01600 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3); 01601 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); 01602 TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); 01603 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); 01604 01605 int bufsize = TIFFScanlineSize(tiff); 01606 tdata_t * buf = new tdata_t[bufsize]; 01607 01608 RGBImageIterator ys(upperleft); 01609 01610 try 01611 { 01612 for(int y=0; y<h; ++y, ++ys.y) 01613 { 01614 uint32 * pr = (uint32 *)buf; 01615 uint32 * pg = pr+1; 01616 uint32 * pb = pg+1; 01617 01618 RGBImageIterator xs(ys); 01619 01620 for(int x=0; x<w; ++x, ++xs.x, pr+=3, pg+=3, pb+=3) 01621 { 01622 *pr = a.red(xs); 01623 *pg = a.green(xs); 01624 *pb = a.blue(xs); 01625 } 01626 TIFFWriteScanline(tiff, buf, y); 01627 } 01628 } 01629 catch(...) 01630 { 01631 delete[] buf; 01632 throw; 01633 } 01634 delete[] buf; 01635 } 01636 01637 template <class RGBImageIterator, class RGBAccessor> 01638 void 01639 createFRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright, 01640 RGBAccessor a, TiffImage * tiff) 01641 { 01642 int w = lowerright.x - upperleft.x; 01643 int h = lowerright.y - upperleft.y; 01644 01645 TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w); 01646 TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h); 01647 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, sizeof(float)*8); 01648 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3); 01649 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); 01650 TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); 01651 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); 01652 01653 int bufsize = TIFFScanlineSize(tiff); 01654 tdata_t * buf = new tdata_t[bufsize]; 01655 01656 RGBImageIterator ys(upperleft); 01657 01658 try 01659 { 01660 for(int y=0; y<h; ++y, ++ys.y) 01661 { 01662 float * pr = (float *)buf; 01663 float * pg = pr+1; 01664 float * pb = pg+1; 01665 01666 RGBImageIterator xs(ys); 01667 01668 for(int x=0; x<w; ++x, ++xs.x, pr+=3, pg+=3, pb+=3) 01669 { 01670 *pr = a.red(xs); 01671 *pg = a.green(xs); 01672 *pb = a.blue(xs); 01673 } 01674 TIFFWriteScanline(tiff, buf, y); 01675 } 01676 } 01677 catch(...) 01678 { 01679 delete[] buf; 01680 throw; 01681 } 01682 delete[] buf; 01683 } 01684 01685 template <class RGBImageIterator, class RGBAccessor> 01686 void 01687 createDRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright, 01688 RGBAccessor a, TiffImage * tiff) 01689 { 01690 int w = lowerright.x - upperleft.x; 01691 int h = lowerright.y - upperleft.y; 01692 01693 TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w); 01694 TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h); 01695 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, sizeof(double)*8); 01696 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3); 01697 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); 01698 TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); 01699 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); 01700 01701 int bufsize = TIFFScanlineSize(tiff); 01702 tdata_t * buf = new tdata_t[bufsize]; 01703 01704 RGBImageIterator ys(upperleft); 01705 01706 try 01707 { 01708 for(int y=0; y<h; ++y, ++ys.y) 01709 { 01710 double * pr = (double *)buf; 01711 double * pg = pr+1; 01712 double * pb = pg+1; 01713 01714 RGBImageIterator xs(ys); 01715 01716 for(int x=0; x<w; ++x, ++xs.x, pr+=3, pg+=3, pb+=3) 01717 { 01718 *pr = a.red(xs); 01719 *pg = a.green(xs); 01720 *pb = a.blue(xs); 01721 } 01722 TIFFWriteScanline(tiff, buf, y); 01723 } 01724 } 01725 catch(...) 01726 { 01727 delete[] buf; 01728 throw; 01729 } 01730 delete[] buf; 01731 } 01732 01733 template <> 01734 struct CreateTiffImage<RGBValue<unsigned char> > 01735 { 01736 template <class ImageIterator, class Accessor> 01737 static void 01738 exec(ImageIterator upperleft, ImageIterator lowerright, 01739 Accessor a, TiffImage * tiff) 01740 { 01741 createBRGBTiffImage(upperleft, lowerright, a, tiff); 01742 } 01743 }; 01744 01745 template <> 01746 struct CreateTiffImage<RGBValue<short> > 01747 { 01748 template <class ImageIterator, class Accessor> 01749 static void 01750 exec(ImageIterator upperleft, ImageIterator lowerright, 01751 Accessor a, TiffImage * tiff) 01752 { 01753 createShortRGBTiffImage(upperleft, lowerright, a, tiff); 01754 } 01755 }; 01756 01757 template <> 01758 struct CreateTiffImage<RGBValue<int> > 01759 { 01760 template <class ImageIterator, class Accessor> 01761 static void 01762 exec(ImageIterator upperleft, ImageIterator lowerright, 01763 Accessor a, TiffImage * tiff) 01764 { 01765 createIRGBTiffImage(upperleft, lowerright, a, tiff); 01766 } 01767 }; 01768 01769 template <> 01770 struct CreateTiffImage<RGBValue<float> > 01771 { 01772 template <class ImageIterator, class Accessor> 01773 static void 01774 exec(ImageIterator upperleft, ImageIterator lowerright, 01775 Accessor a, TiffImage * tiff) 01776 { 01777 createFRGBTiffImage(upperleft, lowerright, a, tiff); 01778 } 01779 }; 01780 01781 template <> 01782 struct CreateTiffImage<RGBValue<double> > 01783 { 01784 template <class ImageIterator, class Accessor> 01785 static void 01786 exec(ImageIterator upperleft, ImageIterator lowerright, 01787 Accessor a, TiffImage * tiff) 01788 { 01789 createDRGBTiffImage(upperleft, lowerright, a, tiff); 01790 } 01791 }; 01792 01793 //@} 01794 01795 } // namespace vigra 01796 01797 01798 #endif /* VIGRA_TIFF_HXX */
© Ullrich Köthe (koethe@informatik.uni-hamburg.de) |
html generated using doxygen and Python
|