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

| vigra/tiff.hxx |
--- | --- | ---

    00001 /************************************************************************/
    00002 /*                                                                      */
    00003 /*               Copyright 1998-2002 by Ullrich Koethe                  */
    00004 /*       Cognitive Systems Group, University of Hamburg, Germany        */
    00005 /*                                                                      */
    00006 /*    This file is part of the VIGRA computer vision library.           */
    00007 /*    ( Version 1.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)