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