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

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

html generated using doxygen and Python
VIGRA 1.6.0 (13 Aug 2008)