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

vigra/tiff.hxx |

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

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.9.0 (Tue Nov 6 2012)