VIGRA - VIGRA: vigra/tiff.hxx Source File

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

# vigra/tiff.hxx

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

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python VIGRA 1.6.0 (13 Aug 2008)