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

OSGDATImageFileType.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 //-------------------------------
00040 //      Includes                                    
00041 //-------------------------------
00042 
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 
00046 #include "OSGConfig.h"
00047 
00048 #include <iostream>
00049 #include <fstream>
00050 
00051 #include <OSGLog.h>
00052 #include <OSGImageFileHandler.h>
00053 #include <OSGPathHandler.h>
00054 #include <OSGFileSystem.h>
00055 #include <OSGZStream.h>
00056 
00057 #include "OSGDATImageFileType.h"
00058 
00059 OSG_USING_NAMESPACE
00060 
00072 /*****************************
00073  *   Types
00074  *****************************/
00075 // Static Class Varible implementations: 
00076 
00077 static const Char8 *suffixArray[] = 
00078 {
00079     "dat"
00080 };
00081 
00082 DATImageFileType DATImageFileType::_the( "dat",
00083                                          suffixArray, sizeof(suffixArray) );
00084 
00085 std::map<std::string, 
00086          DATImageFileType::KeyType   > DATImageFileType::_keyStrMap;
00087 
00088 std::map<std::string, 
00089          DATImageFileType::FormatDesc> DATImageFileType::_formatStrMap;
00090 
00091 /*****************************
00092  *    Classvariables
00093  *****************************/
00094 
00095 
00096 /********************************
00097  *    Class methodes
00098  *******************************/
00099 
00100 //-------------------------------------------------------------------------
00104 DATImageFileType& DATImageFileType::the (void)
00105 {
00106   return _the;
00107 }
00108 
00109 /*******************************
00110 *public
00111 *******************************/
00112 
00113 //-------------------------------------------------------------------------
00118 bool DATImageFileType::read (      ImagePtr &image, 
00119                                    const Char8 *fileName )
00120 {
00121     bool retCode = false;
00122 
00123     std::ifstream inDat(fileName), inVolS;
00124     std::istream *inVol;
00125     std::string keyStr, objectFileName;
00126     const UInt32 lineBufferSize = 1024;
00127     Char8 *value, *keySepPos, lineBuffer[lineBufferSize];
00128     const Char8 keySep = ':';
00129     int fileOffset, keyL, valueL;
00130     std::map<std::string, KeyType>::iterator keyI;
00131     std::map<std::string, FormatDesc>::iterator formatI;
00132     KeyType key;
00133     Image::Type formatType;
00134     UInt32 res[3];
00135     UInt32 bpv, dataSize = 0;
00136     Image::PixelFormat pixelFormat = OSG::Image::OSG_L_PF;
00137     char *dataBuffer = 0;
00138     bool needConversion = false;
00139     // default endian type is big endian
00140     bool big_endian = true;
00141 
00142     res[0] = res[1] = res[2] = 0;
00143     fileOffset = 0;
00144     formatType = Image::OSG_INVALID_IMAGEDATATYPE;
00145     bpv = 0;
00146     dataSize = 0;
00147     dataBuffer = 0;
00148 
00149     initTypeMap();
00150 
00151     beginEditCP(image);
00152 
00153     // read the data file 
00154     for ( lineBuffer[0] = 0; 
00155           inDat.getline ( lineBuffer, lineBufferSize);
00156           lineBuffer[0] = 0 ) 
00157     {        
00158         if ((keySepPos = strchr(lineBuffer,keySep))) 
00159         {
00160             keyL = keySepPos - lineBuffer;
00161             keyStr.assign( lineBuffer, keyL );        
00162             keyI = _keyStrMap.find(keyStr);
00163             key = ((keyI == _keyStrMap.end()) ? UNKNOWN_KT : keyI->second);
00164             value = keySepPos + 1;        
00165             while (value && isspace(*value))
00166                 value++;
00167             valueL = strlen(value);
00168             while (isspace(value[valueL-1]))
00169                 value[--valueL] = 0;
00170             switch (key)
00171             {
00172                 case OBJECT_FILE_NAME_KT:
00173                     objectFileName = value;
00174                     image->setAttachmentField ( keyStr, value );
00175                     break;
00176                 case RESOLUTION_KT:
00177                     sscanf ( value, "%d %d %d", 
00178                              &(res[0]), &(res[1]), &(res[2]));
00179                     image->setAttachmentField ( keyStr, value );
00180                     break;
00181                 case FORMAT_KT:
00182                     formatI = _formatStrMap.find(value);
00183                     if (formatI != _formatStrMap.end())
00184                     {
00185                         formatType = formatI->second.type;
00186                     }
00187                     else 
00188                     {
00189                         formatType = Image::OSG_INVALID_IMAGEDATATYPE;
00190                     }
00191                     image->setAttachmentField ( keyStr, value );
00192                     break;
00193                 case ENDIAN_KT:
00194                     if(!strcmp(value, "LITTLE"))
00195                         big_endian = false;
00196                     image->setAttachmentField ( keyStr, value );
00197                     break;
00198                 case FILE_OFFSET_KT:
00199                     sscanf ( value, "%d", &fileOffset );
00200                     image->setAttachmentField ( keyStr, value );
00201                     break;
00202                 case UNKNOWN_KT:
00203                     FNOTICE (( "Uknown DAT file key: >%s<\n",
00204                                  keyStr.c_str() ));
00205                     image->setAttachmentField ( keyStr, value );
00206                     break;
00207                 case SLICE_THICKNESS_KT:
00208                 default:
00209                     image->setAttachmentField ( keyStr, value );
00210                     break;
00211             }
00212         }
00213         else 
00214         {        
00215             FINFO (("Skip DAT line\n"));
00216         }
00217     }
00218   
00219     // check the setting and read the raw vol data
00220     if (objectFileName.empty() == false) 
00221     {
00222         if ( (res[0] > 0) && (res[1] > 0) && (res[2] > 0) ) 
00223         {
00224             if (formatType != Image::OSG_INVALID_IMAGEDATATYPE) 
00225             {
00226                 inVolS.open(objectFileName.c_str(), 
00227                            std::ios::in | std::ios::binary );
00228                 if (inVolS.fail() && ImageFileHandler::the().getPathHandler())
00229                 {
00230                     // Try to find the file in the search path
00231                     inVolS.clear(); // reset the error state
00232                     PathHandler * ph = ImageFileHandler::the().getPathHandler();
00233                     inVolS.open(ph->findFile(objectFileName.c_str()).c_str(),
00234                                std::ios::in | std::ios::binary );
00235                 }
00236                 if (inVolS.fail())
00237                 {
00238                     // Maybe compressed and name not changed?
00239                     std::string gzname = objectFileName + ".gz";
00240                     inVolS.clear(); // reset the error state
00241                     inVolS.open(gzname.c_str(), 
00242                            std::ios::in | std::ios::binary );
00243                     if (inVolS.fail() && 
00244                         ImageFileHandler::the().getPathHandler())
00245                     {
00246                         // Try to find the file in the search path
00247                         inVolS.clear(); // reset the error state
00248                         PathHandler * ph = ImageFileHandler::the().getPathHandler();
00249                         inVolS.open(ph->findFile(gzname.c_str()).c_str(),
00250                                    std::ios::in | std::ios::binary );
00251                     }
00252                 } 
00253                 if (inVolS.good())
00254                 {                    
00255 #ifdef OSG_ZSTREAM_SUPPORTED
00256                     zip_istream *unzipper = NULL;
00257 #endif
00258 
00259                     image->set ( pixelFormat, res[0], res[1], res[2], 1, 1, 0.0, 0, formatType);
00260                     image->clear();
00261                     
00262                     dataSize = image->getSize();
00263                     
00264                     UInt32 fileDataSize = dataSize;
00265 
00266                     if(isGZip(inVolS))
00267                     {
00268 #ifdef OSG_ZSTREAM_SUPPORTED
00269                         unzipper = new zip_istream(inVolS);
00270                         inVol = unzipper;
00271 #else
00272                         SFATAL << "Compressed streams are not supported! Configure with --enable-png --with-png=DIR options." << std::endl;
00273 #endif
00274                     }
00275                     else
00276                     {
00277                         inVol = &inVolS;
00278 
00279                         // get length of the stream.
00280                         inVol->seekg(0, std::ios::end);
00281                         UInt64 length = inVol->tellg();
00282                         inVol->seekg(0, std::ios::beg);
00283 
00284                         if(length < dataSize - fileOffset)
00285                         {
00286                             // correct dataSize.
00287                             fileDataSize = length;
00288                             FWARNING (( "RAW file length to small!\n" ));
00289                         }
00290                         else if(length > dataSize - fileOffset)
00291                         {
00292                             FWARNING (( "RAW file length to big!\n" ));
00293                         }
00294                     }
00295 
00296                     if (needConversion)
00297                         dataBuffer = new char [ dataSize ];
00298                     else
00299                         dataBuffer = ((char *)(image->getData()));
00300 
00301                     if(fileOffset != 0)
00302                         inVol->ignore ( fileOffset );
00303                     inVol->read ( dataBuffer, fileDataSize );
00304 
00305 #ifdef OSG_ZSTREAM_SUPPORTED
00306                     if(unzipper != NULL)
00307                         delete unzipper;
00308 #endif
00309                 }
00310                 else 
00311                 {
00312                     FWARNING (( "Can not open %s image data\n", 
00313                              objectFileName.c_str() ));
00314                 }
00315             }
00316             else 
00317             {
00318                 FWARNING (( "Invalid/Missing DAT Format\n" ));
00319             }
00320         }
00321         else 
00322         {
00323             FWARNING (( "Invalid/Missing DAT Resolution\n" ));
00324         }
00325     }
00326     else 
00327     {
00328         FWARNING (( "Invalid/Missing DAT ObjectFileName\n" ));
00329     }
00330 
00331     // check/reformat vol data
00332     if (dataSize && dataBuffer)
00333     {
00334         // check host endian type
00335         UInt16 word = 0x0001;
00336         UInt8 *byte = (UInt8 *) &word;
00337         bool host_big_endian = byte[0] ? false : true;
00338 
00339         if(big_endian != host_big_endian)
00340             image->swapDataEndian();
00341     
00342         if (needConversion) 
00343         {
00344             FLOG (("DAT-Data convert not impl. yet !\n"));
00345             {
00346                 switch (formatType)
00347                 {
00348                     case Image::OSG_UINT8_IMAGEDATA:
00349                         break;
00350                     case Image::OSG_UINT16_IMAGEDATA:
00351                         break;
00352                     case Image::OSG_UINT32_IMAGEDATA:
00353                         break;
00354                     case Image::OSG_FLOAT32_IMAGEDATA:
00355                         break;
00356                     default:
00357                         ;
00358                 }
00359             }
00360         }
00361         else 
00362         {
00363             retCode = true;
00364         }
00365     }
00366 
00367 
00368     /* TODO
00369        std::ifstream in(fileName);
00370        Head head;
00371        void *headData = (void*)(&head);
00372        unsigned dataSize, headSize = sizeof(Head);
00373 
00374        if ( in &&        
00375        in.read(static_cast<char *>(headData), 
00376        headSize) && head.netToHost() &&
00377        image.set ( Image::PixelFormat(head.pixelFormat), 
00378        head.width, head.height, head.depth, head.mipmapCount, 
00379        head.frameCount, float(head.frameDelay) / 1000.0) &&
00380        (dataSize = image.getSize()) && 
00381        in.read((char *)(image.getData()), dataSize ))
00382        retCode = true;
00383        else
00384        retCode = false;
00385     */
00386 
00387     endEditCP(image);
00388 
00389     return retCode;
00390 }
00391 
00392 //-------------------------------------------------------------------------
00397 bool DATImageFileType::write(const ImagePtr &image, 
00398                              const Char8 *fileName)
00399 {
00400     initTypeMap();
00401 
00402     // ok we write always in big endian.
00403 #if BYTE_ORDER == LITTLE_ENDIAN
00404     image->swapDataEndian();
00405 #endif
00406 
00407     std::ofstream dat(fileName, std::ios::binary);
00408     if(!dat)
00409     {
00410         SWARNING << "DATImageFileType::write : Can not open output stream for file '" << fileName << "'!" << std::endl;
00411         return false;
00412     }
00413 
00414     Real64 sT[3];
00415     sT[0] = sT[1] = sT[2] = 1.0;
00416     const std::string *attr = image->findAttachmentField("SliceThickness");
00417     if(attr != NULL)
00418          sscanf(attr->c_str(), "%lf %lf %lf", &sT[0], &sT[1], &sT[2]);
00419     
00420     std::string format = "UCHAR";
00421     for(std::map<std::string, FormatDesc>::iterator it = _formatStrMap.begin();
00422         it != _formatStrMap.end();++it)
00423     {
00424         if((*it).second.type == image->getDataType())
00425         {
00426             format = (*it).first;
00427             break;
00428         }
00429     }
00430 
00431     std::string basename = fileName;
00432     std::string::size_type i = basename.rfind(".");
00433     if(i != std::string::npos)
00434         basename = basename.substr(0, i);
00435     basename += ".raw";
00436     
00437     std::string name = basename;
00438     i = name.rfind("/");
00439     // on windows also a / is possible!
00440 #if defined(WIN32)
00441     if(i == std::string::npos)
00442         i = name.rfind("\\");
00443 #endif
00444     if(i != std::string::npos)
00445         name = name.substr(i+1);
00446 
00447     dat << "ObjectFileName: " << name << "\n";
00448     dat << "TaggedFileName: ---\n";
00449     dat << "Resolution:     " << image->getWidth() << " " << image->getHeight()
00450                               << " " << image->getDepth() << "\n";
00451     dat << "SliceThickness: " << sT[0] << " " << sT[1] << " " << sT[2] << "\n";
00452     dat << "Format:         " << format << "\n";
00453     dat << "NbrTags:        0\n";
00454     dat << "ObjectType:     TEXTURE_VOLUME_OBJECT\n";
00455     dat << "ObjectModel:    DENSITY\n";
00456     dat << "GridType:       EQUIDISTANT\n";
00457 
00458     dat.close();
00459     
00460     std::ofstream raw(basename.c_str(), std::ios::binary);
00461     if(!raw)
00462     {
00463         SWARNING << "DATImageFileType::write : Can not open output stream for file '" << basename << "'!" << std::endl;
00464         return false;
00465     }
00466     
00467     raw.write ((const char *) image->getData(), image->getSize());
00468     raw.close();
00469 
00470     // restore to original endian
00471 #if BYTE_ORDER == LITTLE_ENDIAN
00472     image->swapDataEndian();
00473 #endif
00474 
00475     /*
00476     ofstream out(fileName);
00477     Head head;
00478     const void *headData = (void*)(&head);
00479     unsigned dataSize = image.getSize(), headSize = sizeof(Head);
00480 
00481     head.pixelFormat  = image.getPixelFormat();
00482     head.width        = image.getWidth();
00483     head.height       = image.getHeight();
00484     head.depth        = image.getDepth();
00485     head.mipmapCount  = image.getMipMapCount();
00486     head.frameCount   = image.getFrameCount();
00487     head.frameDelay   = short(image.getFrameDelay() * 1000.0);
00488     head.hostToNet();
00489   
00490     if ( out && out.write(static_cast<const char *>(headData), headSize) && 
00491          dataSize &&
00492              out.write((char *)(image.getData()), dataSize) )
00493             retCode = true;
00494     else
00495         retCode = false;    
00496     */
00497 
00498     return true;
00499 }
00500 
00501 
00502 //-------------------------------------------------------------------------
00507 UInt64 DATImageFileType::restoreData(      ImagePtr &image, 
00508                                      const UChar8   *buffer,
00509                                            Int32   OSG_CHECK_ARG(memSize) )
00510 {
00511     image->setData(buffer);
00512 
00513     return image->getSize();
00514 }
00515 
00516 //-------------------------------------------------------------------------
00521 UInt64 DATImageFileType::storeData(const ImagePtr &image, 
00522                                          UChar8   *buffer,
00523                                          Int32     OSG_CHECK_ARG(memSize))
00524 {
00525     UInt32 dataSize = image->getSize();
00526     const UChar8 *src = image->getData();
00527 
00528     if ( dataSize && src && buffer )
00529         memcpy( buffer, src, dataSize);
00530   
00531     return dataSize;
00532 } 
00533 
00534 
00535 //-------------------------------------------------------------------------
00539 DATImageFileType::DATImageFileType ( const Char8 *mimeType,
00540                                      const Char8 *suffixArray[], 
00541                                      UInt16 suffixByteCount )
00542     : ImageFileType ( mimeType, suffixArray, suffixByteCount )
00543 {
00544     return;
00545 }
00546 
00547 //-------------------------------------------------------------------------
00551 DATImageFileType::DATImageFileType (const DATImageFileType &obj )
00552     : ImageFileType(obj)
00553 {
00554     return;
00555 }
00556 
00557 //-------------------------------------------------------------------------
00561 DATImageFileType::~DATImageFileType (void )
00562 {
00563     return;
00564 }
00565 
00566 //-------------------------------------------------------------------------
00570 void DATImageFileType::initTypeMap(void)
00571 {
00572   FormatDesc *desc;
00573 
00574   if (_keyStrMap.empty())
00575     {
00576       _keyStrMap["ObjectFileName"]  = OBJECT_FILE_NAME_KT;
00577       _keyStrMap["Resolution"]      = RESOLUTION_KT;
00578       _keyStrMap["SliceThickness"]  = SLICE_THICKNESS_KT;
00579       _keyStrMap["Format"]          = FORMAT_KT;
00580       _keyStrMap["Endian"]          = ENDIAN_KT;
00581       _keyStrMap["FileOffset"]      = FILE_OFFSET_KT;
00582      }
00583 
00584   if (_formatStrMap.empty())
00585     {
00586       desc = &(_formatStrMap["UCHAR"]);
00587       desc->type = Image::OSG_UINT8_IMAGEDATA;
00588       desc->bpv  = 1;
00589       desc->pixelFormat = Image::OSG_L_PF;
00590       desc->needConversion = false;
00591 
00592       desc = &(_formatStrMap["USHORT"]);
00593       desc->type = Image::OSG_UINT16_IMAGEDATA;
00594       desc->bpv  = 2;
00595       desc->pixelFormat = Image::OSG_L_PF;
00596       desc->needConversion = false;
00597 
00598       desc = &(_formatStrMap["UINT"]);
00599       desc->type = Image::OSG_UINT32_IMAGEDATA;
00600       desc->bpv  = 4; // TODO; is this right ?
00601       desc->pixelFormat = Image::OSG_L_PF;
00602       desc->needConversion = false;
00603 
00604       desc = &(_formatStrMap["ULONG"]);
00605       desc->type = Image::OSG_UINT32_IMAGEDATA;
00606       desc->bpv  = 4;
00607       desc->pixelFormat = Image::OSG_L_PF;
00608       desc->needConversion = false;
00609 
00610       desc = &(_formatStrMap["FLOAT"]);
00611       desc->type = Image::OSG_FLOAT32_IMAGEDATA;
00612       desc->bpv  = 4;
00613       desc->pixelFormat = Image::OSG_L_PF;
00614       desc->needConversion = false;
00615 
00616       desc = &(_formatStrMap["DOUBLE"]);
00617       desc->type = Image::OSG_FLOAT32_IMAGEDATA; // we have no OSG_FLOAT64_IMAGEDATA
00618       desc->bpv  = 8;
00619       desc->pixelFormat = Image::OSG_L_PF;
00620       desc->needConversion = false;
00621     }
00622 
00623 }
00624 

Generated on Thu Aug 25 04:02:32 2005 for OpenSG by  doxygen 1.4.3