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