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