Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGTIFImageFileType.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 //-------------------------------
00039 // Includes  
00040 //-------------------------------
00041 
00042 #ifdef __hpux // prevent int32 clash (model.h/tiff.h)  
00043 #define _INT32
00044 #endif
00045 
00046 #include <stdlib.h>
00047 #include <stdio.h>
00048 
00049 #include "OSGConfig.h"
00050 
00051 #include "OSGTIFImageFileType.h"
00052 
00053 #ifdef OSG_WITH_TIF
00054 #include <tiffio.h>
00055 #endif
00056 #include <OSGLog.h>
00057 
00058 #ifndef OSG_DO_DOC
00059 #    ifdef OSG_WITH_TIF
00060 #        define OSG_TIF_ARG(ARG) ARG
00061 #    else
00062 #        define OSG_TIF_ARG(ARG)
00063 #    endif
00064 #else
00065 #    define OSG_TIF_ARG(ARG) ARG
00066 #endif
00067 
00068 
00069 OSG_USING_NAMESPACE
00070 
00071 
00087 static void warningHandler (const char *module, const char *fmt, va_list ap)
00088 {
00089     Char8   buffer[4096];
00090 
00091 #ifdef OSG_HAS_VSNPRINTF
00092     vsnprintf(buffer, sizeof(buffer) - 1, fmt, ap);
00093 #else
00094     vsprintf(buffer, fmt, ap);
00095 #endif
00096 
00097     FWARNING (("TiffLib: %s;%s\n", module ? module : "Mod", buffer));
00098 }
00099 
00100 static void errorHandler (const char *module, const char *fmt, va_list ap)
00101 {
00102     Char8   buffer[4096];
00103 
00104 #ifdef OSG_HAS_VSNPRINTF
00105     vsnprintf(buffer, sizeof(buffer) - 1, fmt, ap);
00106 #else
00107     vsprintf(buffer, fmt, ap);
00108 #endif
00109 
00110     FFATAL (("TiffLib: %s;%s\n", module ? module : "Mod", buffer));
00111 }
00112 
00113 
00114 // Static Class Varible implementations:
00115 static const Char8 *suffixArray[] = {
00116   "tif", "tiff"
00117 };
00118 
00119 TIFImageFileType TIFImageFileType:: _the("tiff",
00120                                          suffixArray, sizeof(suffixArray),
00121                                          OSG_READ_SUPPORTED | 
00122                                          OSG_WRITE_SUPPORTED);
00123 
00124 /* enum VecBase::VectorSizeE
00125  * brief 
00126 */
00127 
00128 /* var VecBase::VectorSizeE VecBase::_iSize
00129  *
00130 */
00131 
00132 /* const char *VecBase::getClassName(void)
00133  *  brief Classname
00134 */
00135 
00136 /* var ValueTypeT VecBase:: _value[Size];
00137  * brief value store
00138 */
00139 
00140 /*****************************
00141  *   Types
00142  *****************************/
00143 
00144 /*****************************
00145  *  Classvariables
00146  *****************************/
00147 
00148 /********************************
00149  *  Class methodes
00150  *******************************/
00151 
00152 //-------------------------------------------------------------------------
00156 TIFImageFileType& TIFImageFileType::the (void)
00157 {
00158   static bool initTIFFLib = true;
00159 
00160 #ifdef OSG_WITH_TIF
00161 
00162   if (initTIFFLib) 
00163   {
00164     initTIFFLib = false;
00165 
00166     TIFFSetWarningHandler(&warningHandler);
00167     TIFFSetErrorHandler(&errorHandler);
00168   }
00169 
00170 #endif
00171 
00172   return _the;
00173 }
00174 
00175 
00176 /*******************************
00177 *public
00178 *******************************/
00179 
00180 //-------------------------------------------------------------------------
00185 bool TIFImageFileType::read(      ImagePtr &OSG_TIF_ARG(image), 
00186                             const Char8    *OSG_TIF_ARG(fileName))
00187 {
00188     bool    valid = false;
00189 
00190 #ifdef OSG_WITH_TIF
00191     TIFF    *in = TIFFOpen(fileName, "r");
00192     UChar8  *data = 0, *line = 0, *dest;
00193     UInt32  w, h, u, v;
00194     UInt16  bpp;
00195     Char8   errorMessage[1024];
00196     UInt16  *sampleinfo;
00197     UInt16  extrasamples;
00198     UInt16  si;
00199     UInt16  red, green, blue, alpha;
00200 
00201     if(in)
00202     {
00203         TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w);
00204 
00205         TIFFGetField(in, TIFFTAG_IMAGELENGTH, &h);
00206 
00207         TIFFGetFieldDefaulted(in, TIFFTAG_SAMPLESPERPIXEL, &bpp);
00208 
00209         if(bpp == 4)
00210         {   // accept unspecified extra samples as associated alpha
00211             TIFFGetFieldDefaulted(in, TIFFTAG_EXTRASAMPLES, &extrasamples,
00212                                   &sampleinfo);
00213 
00214             if(sampleinfo && sampleinfo[0] == EXTRASAMPLE_UNSPECIFIED)
00215             {
00216                 si = EXTRASAMPLE_ASSOCALPHA;
00217                 TIFFSetField(in, TIFFTAG_EXTRASAMPLES, 1, &si);
00218             }
00219         }
00220 
00221         data = new UChar8[w * h * 4];
00222         if(TIFFRGBAImageOK(in, errorMessage) &&
00223            TIFFReadRGBAImage(in, w, h, (uint32 *) data, 1))
00224             valid = true;
00225         else
00226         {
00227             SWARNING << "Tiff reader failed: " << errorMessage << std::endl;
00228             valid = false;
00229         }
00230 
00231         if(valid)
00232         {
00233             Image::PixelFormat  type = osg::Image::OSG_INVALID_PF;
00234             switch(bpp)
00235             {
00236             case 1:
00237                 type = Image::OSG_L_PF;
00238                 break;
00239             case 2:
00240                 type = Image::OSG_LA_PF;
00241                 break;
00242             case 3:
00243                 type = Image::OSG_RGB_PF;
00244                 break;
00245             case 4:
00246                 type = Image::OSG_RGBA_PF;
00247                 break;
00248             }
00249 
00250             image->set(type, w, h);
00251             dest = image->getData();
00252 
00253 #if defined(__linux) || defined(_WIN32)
00254             red = 0;
00255             green = 1;
00256             blue = 2;
00257             alpha = 3;
00258 
00259 #else
00260             red = 3;
00261             green = 2;
00262             blue = 1;
00263             alpha = 0;
00264 #endif
00265             for(v = 0; v < h; v++)
00266             {
00267                 line = data + ((v) * (w * 4));
00268                 for(u = 0; u < w; u++)
00269                 {
00270                     switch(bpp)
00271                     {
00272                     case 4:
00273                         *dest++ = line[red];
00274                         *dest++ = line[green];
00275                         *dest++ = line[blue];
00276                         *dest++ = line[alpha];
00277                         break;
00278                     case 3:
00279                         *dest++ = line[red];
00280                         *dest++ = line[green];
00281                         *dest++ = line[blue];
00282                         break;
00283                     case 2:
00284                         *dest++ = line[red];
00285                         *dest++ = line[green];
00286                         break;
00287                     case 1:
00288                         *dest++ = line[red];
00289                         break;
00290                     }
00291 
00292                     line += 4;
00293                 }
00294             }
00295 
00296             TIFFClose(in);
00297             delete[] data;
00298             data = 0;
00299         }
00300     }
00301 
00302 #else
00303     SWARNING <<
00304         getMimeType() <<
00305         " read is not compiled into the current binary " <<
00306         std::endl;
00307 #endif
00308     return valid;
00309 }
00310 
00311 //-------------------------------------------------------------------------
00316 bool TIFImageFileType::write(const ImagePtr &OSG_TIF_ARG(image),
00317                              const Char8    *OSG_TIF_ARG(fileName))
00318 {
00319     bool                retCode = false;
00320 
00321 #ifdef OSG_WITH_TIF
00322     
00323     if(image->getDimension() < 1 || image->getDimension() > 2)
00324     {
00325         FWARNING(("TIFImageFileType::write: invalid dimension %d!\n",
00326             image->getDimension()));
00327         return false;
00328     }
00329 
00330     TIFF                *out = TIFFOpen(fileName, "w");
00331     int                 lineSize = image->getWidth() * image->getBpp();
00332     int                 photometric = 0, samplesPerPixel = 0;
00333     const UChar8       *data;
00334     int                 row;
00335 
00336     // TODO: implemet all cases correct
00337     switch(image->getBpp())
00338     {
00339     case 1:
00340         samplesPerPixel = 1;
00341         photometric = PHOTOMETRIC_MINISBLACK;
00342         break;
00343     case 2:
00344         samplesPerPixel = 2;
00345         photometric = PHOTOMETRIC_MINISBLACK;
00346         break;
00347     case 3:
00348         samplesPerPixel = 3;
00349         photometric = PHOTOMETRIC_RGB;
00350         break;
00351     case 4:
00352         samplesPerPixel = 4;
00353         photometric = PHOTOMETRIC_RGB;
00354         break;
00355     }
00356 
00357     if(out)
00358     {
00359         TIFFSetField(out, TIFFTAG_IMAGEWIDTH, image->getWidth());
00360         TIFFSetField(out, TIFFTAG_IMAGELENGTH, image->getHeight());
00361         TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
00362         TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, samplesPerPixel);
00363         TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
00364         TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
00365         TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
00366         TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
00367         TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, 0));
00368 
00369         for(row = 0; row < image->getHeight(); row++)
00370         {
00371             data = image->getData() + ((image->getHeight() - row - 1) * lineSize);
00372             if(TIFFWriteScanline(out, 
00373                                  (tdata_t) const_cast<UChar8 *>(data), 
00374                                  row, 
00375                                  0) < 0)
00376                 break;
00377         }
00378 
00379         TIFFClose(out);
00380         retCode = true;
00381     }
00382 
00383 #else
00384     SWARNING <<
00385         getMimeType() <<
00386         " write is not compiled into the current binary " <<
00387         std::endl;
00388 #endif
00389     return retCode;
00390 }
00391 
00392 bool TIFImageFileType::validateHeader( const Char8 *fileName, bool &implemented)
00393 {
00394     implemented = true;
00395 
00396     if(fileName == NULL)
00397         return false;
00398 
00399     FILE *file = fopen(fileName, "rb");
00400     if(file == NULL)
00401         return false;
00402 
00403     std::string magic;
00404     magic.resize(2);
00405     fread((void *) &magic[0], 2, 1, file);
00406     fclose(file);
00407 
00408     if(magic == "MM" || magic == "II")
00409     {
00410         return true;
00411     }
00412 
00413     return false;
00414 }
00415 
00416 /******************************
00417 *protected 
00418 ******************************/
00419 
00420 /******************************
00421 *private
00422 ******************************/
00423 
00424 /***************************
00425 *instance methodes 
00426 ***************************/
00427 
00428 /***************************
00429 *public
00430 ***************************/
00431 
00434 //-------------------------------------------------------------------------
00438 TIFImageFileType::TIFImageFileType(const Char8 *mimeType,
00439                                    const Char8 *suffixArray[],
00440                                    UInt16 suffixByteCount,
00441                                    UInt32 flags) :
00442     ImageFileType(mimeType,suffixArray, suffixByteCount, flags)
00443 {
00444     the();
00445 }
00446 
00447 //-------------------------------------------------------------------------
00451 TIFImageFileType::TIFImageFileType(const TIFImageFileType &obj) :
00452     ImageFileType(obj)
00453 {
00454     the();
00455 }
00456 
00457 //-------------------------------------------------------------------------
00461 TIFImageFileType::~TIFImageFileType(void)
00462 {
00463     return;
00464 }

Generated on Thu Aug 25 04:11:39 2005 for OpenSG by  doxygen 1.4.3