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

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

html generated using doxygen and Python
VIGRA 1.6.0 (5 Nov 2009)