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