[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

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

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.7.0 (Thu Aug 25 2011)