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

OSGTGAImageFileType.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 #include "OSGBaseFunctions.h"
00051 
00052 #include "OSGTGAImageFileType.h"
00053 
00054 #ifdef OSG_WITH_TGA
00055 #include <tiffio.h>
00056 #endif
00057 #include <OSGLog.h>
00058 
00059 
00060 OSG_USING_NAMESPACE
00061 
00062 
00075 // Static Class Varible implementations:
00076 static const Char8 *suffixArray[] = {
00077   "tga"
00078 };
00079 
00080 //-------------------------------------------------------------------------
00084 TGAImageFileType& TGAImageFileType::the (void)
00085 {
00086   return _the;
00087 }
00088 
00089 void TGAImageFileType::readHeader(std::istream &in, TGAHeader &header)
00090 {
00091     UInt8 dum[18];
00092 
00093     in.read(reinterpret_cast<char *>(dum), 18);
00094 
00095     header.idLength      = dum[ 0];
00096     header.colorMapType  = dum[ 1];
00097     header.imageType     = dum[ 2];
00098     header.cmapEntrySize = dum[ 7];
00099     header.depth         = dum[16];
00100     header.descriptor    = dum[17];
00101 
00102     if(osgIsBigEndian())
00103     {
00104         header.cmapFirst  = dum[ 4] + dum[ 3] * 256;
00105         header.cmapLength = dum[ 6] + dum[ 5] * 256;
00106         header.xOrigin    = dum[ 9] + dum[ 8] * 256;
00107         header.yOrigin    = dum[11] + dum[10] * 256;
00108         header.width      = dum[13] + dum[12] * 256;
00109         header.height     = dum[15] + dum[14] * 256;
00110     }
00111     else
00112     {
00113         header.cmapFirst  = dum[ 3] + dum[ 4] * 256;
00114         header.cmapLength = dum[ 5] + dum[ 6] * 256;
00115         header.xOrigin    = dum[ 8] + dum[ 9] * 256;
00116         header.yOrigin    = dum[10] + dum[11] * 256;
00117         header.width      = dum[12] + dum[13] * 256;
00118         header.height     = dum[14] + dum[15] * 256;
00119     }
00120 }
00121 
00122 bool TGAImageFileType::readCompressedImageData(std::istream &in, ImagePtr &image)
00123 {
00124     UInt32 npix = image->getWidth() * image->getHeight();
00125     UInt8   rep;
00126     UChar8 *data = image->getData();
00127     UInt16 bpp = image->getBpp();
00128     UChar8 r,g,b,a;
00129 
00130     while(npix)
00131     {
00132         in.read(reinterpret_cast<char *>(&rep), 1);
00133 
00134         if(rep & 0x80)
00135         {
00136             rep = (rep & 0x7f) + 1;
00137             npix -= rep;
00138 
00139             switch(image->getPixelFormat())
00140             {
00141                 case Image::OSG_L_PF:
00142                     in.read(reinterpret_cast<char *>(&a), 1);
00143                     while(rep--)
00144                     {
00145                         *data++ = a;
00146                     }
00147                     break;
00148                 case Image::OSG_RGB_PF:
00149                     in.read(reinterpret_cast<char *>(&b), 1);
00150                     in.read(reinterpret_cast<char *>(&g), 1);
00151                     in.read(reinterpret_cast<char *>(&r), 1);
00152                     while(rep--)
00153                     {
00154                         *data++ = b;
00155                         *data++ = g;
00156                         *data++ = r;
00157                     }
00158                     break;
00159                 case Image::OSG_RGBA_PF:
00160                     in.read(reinterpret_cast<char *>(&b), 1);
00161                     in.read(reinterpret_cast<char *>(&g), 1);
00162                     in.read(reinterpret_cast<char *>(&r), 1);
00163                     in.read(reinterpret_cast<char *>(&a), 1);
00164                     while(rep--)
00165                     {
00166                         *data++ = b;
00167                         *data++ = g;
00168                         *data++ = r;
00169                         *data++ = a;
00170                     }
00171                     break;
00172                 default:
00173                     FWARNING(("TGA: unknown pixel "
00174                               "format!?!\n"));
00175                     return false;
00176             }
00177         }
00178         else // raw packet
00179         {
00180             rep = (rep & 0x7f) + 1;
00181             in.read(reinterpret_cast<char *>(data), bpp * rep);
00182             data += rep * bpp;
00183             npix -= rep;
00184         }
00185     }
00186     return true;
00187 }
00188 
00189 
00190 TGAImageFileType TGAImageFileType::_the("tga",
00191                                         suffixArray, sizeof(suffixArray));
00192 
00193 
00194 //-------------------------------------------------------------------------
00199 bool TGAImageFileType::read(      ImagePtr &image,
00200                             const Char8    *fileName)
00201 {
00202     std::ifstream  in(fileName, std::ios::in | std::ios::binary);
00203 
00204     if(! in.rdbuf()->is_open())
00205     {
00206         FWARNING(("Error opening TGA file %s!\n", fileName));
00207         return false;
00208     }
00209 
00210     TGAHeader header;
00211     readHeader(in, header);
00212 
00213     Image::PixelFormat format = Image::OSG_INVALID_PF;
00214 
00215     bool    compressed = (header.imageType & 0x8) != 0;
00216 
00217     switch(header.imageType & ~0x8)
00218     {
00219     case 1:     FWARNING(("TGA: 8-bit image not supported!\n"));
00220                 break;
00221 
00222     case 2:     switch(header.depth)
00223                 {
00224                 case 24:    format = Image::OSG_RGB_PF;
00225                             break;
00226                 case 32:    format = Image::OSG_RGBA_PF;
00227                             break;
00228                 default:    FWARNING(("TGA: Unknown pixel depth %d!\n",
00229                                     header.depth));
00230                             break;
00231                 }
00232                 break;
00233 
00234     case 3:     format = Image::OSG_L_PF;
00235                 break;
00236     }
00237 
00238     if(format == Image::OSG_INVALID_PF)
00239     {
00240        FWARNING(("Unsupported image type for TGA file %s!\n", fileName));
00241        return false;
00242     }
00243 
00244     image->set(format, header.width, header.height);
00245 
00246     // read the image ID
00247     UInt8 imageid[256];
00248     in.read(reinterpret_cast<char *>(imageid), header.idLength);
00249     imageid[header.idLength] = 0;
00250 
00251     FDEBUG(("TGA: Image ID '%s'\n", imageid));
00252 
00253     // read color map data
00254     if(header.colorMapType == 1)
00255     {
00256         UInt32 len = osgMin(header.cmapEntrySize / 3, 8) * header.cmapLength;
00257 
00258         UInt8 * dum = new UInt8 [len];
00259 
00260         in.read(reinterpret_cast<char *>(dum), len);
00261 
00262         delete [] dum;
00263     }
00264 
00265     // read image data
00266     if(compressed)
00267     {
00268         if(!readCompressedImageData(in, image))
00269         {
00270             FWARNING(("Unsupported image type for TGA file %s!\n", fileName));
00271             return false;
00272         }
00273     }
00274     else
00275     {
00276         in.read(reinterpret_cast<char *>(image->getData()),
00277                 static_cast<int>(image->getSize()));
00278     }
00279 
00280     // check origin
00281     switch(header.descriptor & 0x30)
00282     {
00283     case 0x00:  // bottom left, ok!
00284                 break;
00285     case 0x10:  // bottom right
00286     case 0x20:  // top left
00287     case 0x30:  // top right
00288                 FWARNING(("TGA: origin 0x%d not supported!\n",
00289                           header.descriptor & 0x30));
00290                 return false;
00291     }
00292 
00293     // do BGR -> RGB swap, as GL_BGR_EXT is not supported everywhere
00294     if(image->getPixelFormat() == Image::OSG_RGB_PF ||
00295        image->getPixelFormat() == Image::OSG_RGBA_PF)
00296     {
00297         UChar8 *d    = image->getData(), dum;
00298         UInt32  npix = image->getWidth() * image->getHeight();
00299         UInt8   bpp  = image->getBpp();
00300 
00301         while(npix--)
00302         {
00303             dum  = d[2];
00304             d[2] = d[0];
00305             d[0] = dum;
00306             d += bpp;
00307         }
00308     }
00309 
00310     return true;
00311 }
00312 
00313 //-------------------------------------------------------------------------
00318 bool TGAImageFileType::write(const ImagePtr &,
00319                              const Char8    *OSG_CHECK_ARG(fileName))
00320 {
00321     SWARNING <<
00322         getMimeType() <<
00323         " write is not compiled into the current binary " <<
00324         std::endl;
00325 
00326     return true;
00327 }
00328 
00329 //-------------------------------------------------------------------------
00333 TGAImageFileType::TGAImageFileType(const Char8 *mimeType,
00334                                    const Char8 *suffixArray[],
00335                                    UInt16 suffixByteCount) :
00336     ImageFileType(mimeType,suffixArray, suffixByteCount)
00337 {
00338     return;
00339 }
00340 
00341 //-------------------------------------------------------------------------
00345 TGAImageFileType::TGAImageFileType(const TGAImageFileType &obj) :
00346     ImageFileType(obj)
00347 {
00348     return;
00349 }
00350 
00351 //-------------------------------------------------------------------------
00355 TGAImageFileType::~TGAImageFileType(void)
00356 {
00357     return;
00358 }

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