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

details vigra/tiff.hxx VIGRA

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

© Ullrich Köthe (koethe@informatik.uni-hamburg.de)
Cognitive Systems Group, University of Hamburg, Germany

html generated using doxygen and Python
VIGRA 1.4.0 (21 Dec 2005)