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

© Ullrich Köthe (koethe@informatik.uni-hamburg.de) Cognitive Systems Group, University of Hamburg, Germany | html generated using doxygen and Python VIGRA 1.5.0 (7 Dec 2006)