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