00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
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
00074
00075
00076
00077 static const Char8 *suffixArray[] =
00078 {
00079 "dat"
00080 };
00081
00082 DATImageFileType DATImageFileType::_the( "image/x-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
00093
00094
00095
00096
00097
00098
00099
00100
00104 DATImageFileType& DATImageFileType::the (void)
00105 {
00106 return _the;
00107 }
00108
00109
00110
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 channel = 1;
00135 UInt32 res[3];
00136 UInt32 dataSize = 0;
00137 Image::PixelFormat pixelFormat;
00138 char *dataBuffer = 0;
00139 bool needConversion = false;
00140
00141 bool big_endian = true;
00142
00143 res[0] = res[1] = res[2] = 0;
00144 fileOffset = 0;
00145 formatType = Image::OSG_INVALID_IMAGEDATATYPE;
00146 dataSize = 0;
00147 dataBuffer = 0;
00148
00149 initTypeMap();
00150
00151 beginEditCP(image);
00152
00153
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 CHANNEL_KT:
00177 sscanf ( value, "%d", &(channel) );
00178 image->setAttachmentField ( keyStr, value );
00179 break;
00180 case RESOLUTION_KT:
00181 sscanf ( value, "%d %d %d",
00182 &(res[0]), &(res[1]), &(res[2]));
00183 image->setAttachmentField ( keyStr, value );
00184 break;
00185 case FORMAT_KT:
00186 formatI = _formatStrMap.find(value);
00187 if (formatI != _formatStrMap.end())
00188 {
00189 formatType = formatI->second.type;
00190 }
00191 else
00192 {
00193 formatType = Image::OSG_INVALID_IMAGEDATATYPE;
00194 }
00195 image->setAttachmentField ( keyStr, value );
00196 break;
00197 case ENDIAN_KT:
00198 if(!strcmp(value, "LITTLE"))
00199 big_endian = false;
00200 image->setAttachmentField ( keyStr, value );
00201 break;
00202 case FILE_OFFSET_KT:
00203 sscanf ( value, "%d", &fileOffset );
00204 image->setAttachmentField ( keyStr, value );
00205 break;
00206 case UNKNOWN_KT:
00207 FNOTICE (( "Uknown DAT file key: >%s<\n",
00208 keyStr.c_str() ));
00209 image->setAttachmentField ( keyStr, value );
00210 break;
00211 case SLICE_THICKNESS_KT:
00212 default:
00213 image->setAttachmentField ( keyStr, value );
00214 break;
00215 }
00216 }
00217 else
00218 {
00219 FINFO (("Skip DAT line\n"));
00220 }
00221 }
00222
00223
00224 switch (channel) {
00225 case 4:
00226 pixelFormat = osg::Image::OSG_RGBA_PF;
00227 break;
00228 case 3:
00229 pixelFormat = osg::Image::OSG_RGB_PF;
00230 break;
00231 case 2:
00232 pixelFormat = osg::Image::OSG_LA_PF;
00233 break;
00234 default:
00235 pixelFormat = osg::Image::OSG_L_PF;
00236 break;
00237 }
00238
00239
00240 if (objectFileName.empty() == false)
00241 {
00242 if ( (res[0] > 0) && (res[1] > 0) && (res[2] > 0) )
00243 {
00244 if (formatType != Image::OSG_INVALID_IMAGEDATATYPE)
00245 {
00246 inVolS.open(objectFileName.c_str(),
00247 std::ios::in | std::ios::binary );
00248 if (inVolS.fail() && ImageFileHandler::the().getPathHandler())
00249 {
00250
00251 inVolS.clear();
00252 PathHandler * ph = ImageFileHandler::the().getPathHandler();
00253 inVolS.open(ph->findFile(objectFileName.c_str()).c_str(),
00254 std::ios::in | std::ios::binary );
00255 }
00256 if (inVolS.fail())
00257 {
00258
00259 std::string gzname = objectFileName + ".gz";
00260 inVolS.clear();
00261 inVolS.open(gzname.c_str(),
00262 std::ios::in | std::ios::binary );
00263 if (inVolS.fail() &&
00264 ImageFileHandler::the().getPathHandler())
00265 {
00266
00267 inVolS.clear();
00268 PathHandler * ph = ImageFileHandler::the().getPathHandler();
00269 inVolS.open(ph->findFile(gzname.c_str()).c_str(),
00270 std::ios::in | std::ios::binary );
00271 }
00272 }
00273 if (inVolS.good())
00274 {
00275 #ifdef OSG_ZSTREAM_SUPPORTED
00276 zip_istream *unzipper = NULL;
00277 #endif
00278
00279 image->set ( pixelFormat, res[0], res[1], res[2], 1, 1, 0.0, 0, formatType);
00280 image->clear();
00281
00282 dataSize = image->getSize();
00283
00284 UInt32 fileDataSize = dataSize;
00285
00286 if(isGZip(inVolS))
00287 {
00288 #ifdef OSG_ZSTREAM_SUPPORTED
00289 unzipper = new zip_istream(inVolS);
00290 inVol = unzipper;
00291 #else
00292 SFATAL << "Compressed streams are not supported! Configure with --enable-png --with-png=DIR options." << std::endl;
00293 #endif
00294 }
00295 else
00296 {
00297 inVol = &inVolS;
00298
00299
00300 inVol->seekg(0, std::ios::end);
00301 UInt64 length = inVol->tellg();
00302 inVol->seekg(0, std::ios::beg);
00303
00304 if(length < dataSize - fileOffset)
00305 {
00306
00307 fileDataSize = length;
00308 FWARNING (( "RAW file length to small!\n" ));
00309 }
00310 else if(length > dataSize - fileOffset)
00311 {
00312 FWARNING (( "RAW file length to big!\n" ));
00313 }
00314 }
00315
00316 if (needConversion)
00317 dataBuffer = new char [ dataSize ];
00318 else
00319 dataBuffer = ((char *)(image->getData()));
00320
00321 if(fileOffset != 0)
00322 inVol->ignore ( fileOffset );
00323 inVol->read ( dataBuffer, fileDataSize );
00324
00325 #ifdef OSG_ZSTREAM_SUPPORTED
00326 if(unzipper != NULL)
00327 delete unzipper;
00328 #endif
00329 }
00330 else
00331 {
00332 FWARNING (( "Can not open %s image data\n",
00333 objectFileName.c_str() ));
00334 }
00335 }
00336 else
00337 {
00338 FWARNING (( "Invalid/Missing DAT Format\n" ));
00339 }
00340 }
00341 else
00342 {
00343 FWARNING (( "Invalid/Missing DAT Resolution\n" ));
00344 }
00345 }
00346 else
00347 {
00348 FWARNING (( "Invalid/Missing DAT ObjectFileName\n" ));
00349 }
00350
00351
00352 if (dataSize && dataBuffer)
00353 {
00354
00355 UInt16 word = 0x0001;
00356 UInt8 *byte = (UInt8 *) &word;
00357 bool host_big_endian = byte[0] ? false : true;
00358
00359 if(big_endian != host_big_endian)
00360 image->swapDataEndian();
00361
00362 if (needConversion)
00363 {
00364 FLOG (("DAT-Data convert not impl. yet !\n"));
00365 {
00366 switch (formatType)
00367 {
00368 case Image::OSG_UINT8_IMAGEDATA:
00369 break;
00370 case Image::OSG_UINT16_IMAGEDATA:
00371 break;
00372 case Image::OSG_UINT32_IMAGEDATA:
00373 break;
00374 case Image::OSG_FLOAT32_IMAGEDATA:
00375 break;
00376 default:
00377 ;
00378 }
00379 }
00380 }
00381 else
00382 {
00383 retCode = true;
00384 }
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 endEditCP(image);
00408
00409 return retCode;
00410 }
00411
00412
00417 bool DATImageFileType::write(const ImagePtr &image,
00418 const Char8 *fileName)
00419 {
00420 initTypeMap();
00421
00422
00423 #if BYTE_ORDER == LITTLE_ENDIAN
00424 image->swapDataEndian();
00425 #endif
00426
00427 std::ofstream dat(fileName, std::ios::binary);
00428 if(!dat)
00429 {
00430 SWARNING << "DATImageFileType::write : Can not open output stream for file '" << fileName << "'!" << std::endl;
00431 return false;
00432 }
00433
00434 Real64 sT[3];
00435 sT[0] = sT[1] = sT[2] = 1.0;
00436 const std::string *attr = image->findAttachmentField("SliceThickness");
00437 if(attr != NULL)
00438 sscanf(attr->c_str(), "%lf %lf %lf", &sT[0], &sT[1], &sT[2]);
00439
00440 std::string format = "UCHAR";
00441 for(std::map<std::string, FormatDesc>::iterator it = _formatStrMap.begin();
00442 it != _formatStrMap.end();++it)
00443 {
00444 if((*it).second.type == image->getDataType())
00445 {
00446 format = (*it).first;
00447 break;
00448 }
00449 }
00450
00451 std::string basename = fileName;
00452 std::string::size_type i = basename.rfind(".");
00453 if(i != std::string::npos)
00454 basename = basename.substr(0, i);
00455 basename += ".raw";
00456
00457 std::string name = basename;
00458 i = name.rfind("/");
00459
00460 #if defined(WIN32)
00461 if(i == std::string::npos)
00462 i = name.rfind("\\");
00463 #endif
00464 if(i != std::string::npos)
00465 name = name.substr(i+1);
00466
00467 dat << "ObjectFileName: " << name << "\n";
00468 dat << "TaggedFileName: ---\n";
00469 dat << "Resolution: " << image->getWidth() << " " << image->getHeight()
00470 << " " << image->getDepth() << "\n";
00471 dat << "SliceThickness: " << sT[0] << " " << sT[1] << " " << sT[2] << "\n";
00472 dat << "Format: " << format << "\n";
00473 dat << "NbrTags: 0\n";
00474 dat << "ObjectType: TEXTURE_VOLUME_OBJECT\n";
00475 dat << "ObjectModel: DENSITY\n";
00476 dat << "GridType: EQUIDISTANT\n";
00477
00478 if (image->getBpp() > 1)
00479 dat << "Channel: " << image->getBpp() << "\n";
00480
00481 dat.close();
00482
00483 std::ofstream raw(basename.c_str(), std::ios::binary);
00484 if(!raw)
00485 {
00486 SWARNING << "DATImageFileType::write : Can not open output stream for file '" << basename << "'!" << std::endl;
00487 return false;
00488 }
00489
00490 raw.write ((const char *) image->getData(), image->getSize());
00491 raw.close();
00492
00493
00494 #if BYTE_ORDER == LITTLE_ENDIAN
00495 image->swapDataEndian();
00496 #endif
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 return true;
00522 }
00523
00524
00529 UInt64 DATImageFileType::restoreData( ImagePtr &image,
00530 const UChar8 *buffer,
00531 Int32 OSG_CHECK_ARG(memSize) )
00532 {
00533 image->setData(buffer);
00534
00535 return image->getSize();
00536 }
00537
00538
00543 UInt64 DATImageFileType::storeData(const ImagePtr &image,
00544 UChar8 *buffer,
00545 Int32 OSG_CHECK_ARG(memSize))
00546 {
00547 UInt32 dataSize = image->getSize();
00548 const UChar8 *src = image->getData();
00549
00550 if ( dataSize && src && buffer )
00551 memcpy( buffer, src, dataSize);
00552
00553 return dataSize;
00554 }
00555
00556
00557
00561 DATImageFileType::DATImageFileType ( const Char8 *mimeType,
00562 const Char8 *suffixArray[],
00563 UInt16 suffixByteCount )
00564 : ImageFileType ( mimeType, suffixArray, suffixByteCount )
00565 {}
00566
00567
00571 DATImageFileType::~DATImageFileType (void ) {}
00572
00573
00577 void DATImageFileType::initTypeMap(void)
00578 {
00579 FormatDesc *desc;
00580
00581 if (_keyStrMap.empty())
00582 {
00583 _keyStrMap["ObjectFileName"] = OBJECT_FILE_NAME_KT;
00584 _keyStrMap["Resolution"] = RESOLUTION_KT;
00585 _keyStrMap["Channel"] = CHANNEL_KT;
00586 _keyStrMap["SliceThickness"] = SLICE_THICKNESS_KT;
00587 _keyStrMap["Format"] = FORMAT_KT;
00588 _keyStrMap["Endian"] = ENDIAN_KT;
00589 _keyStrMap["FileOffset"] = FILE_OFFSET_KT;
00590 }
00591
00592 if (_formatStrMap.empty())
00593 {
00594 desc = &(_formatStrMap["UCHAR"]);
00595 desc->type = Image::OSG_UINT8_IMAGEDATA;
00596 desc->bpv = 1;
00597 desc->pixelFormat = Image::OSG_L_PF;
00598 desc->needConversion = false;
00599
00600 desc = &(_formatStrMap["USHORT"]);
00601 desc->type = Image::OSG_UINT16_IMAGEDATA;
00602 desc->bpv = 2;
00603 desc->pixelFormat = Image::OSG_L_PF;
00604 desc->needConversion = false;
00605
00606 desc = &(_formatStrMap["UINT"]);
00607 desc->type = Image::OSG_UINT32_IMAGEDATA;
00608 desc->bpv = 4;
00609 desc->pixelFormat = Image::OSG_L_PF;
00610 desc->needConversion = false;
00611
00612 desc = &(_formatStrMap["ULONG"]);
00613 desc->type = Image::OSG_UINT32_IMAGEDATA;
00614 desc->bpv = 4;
00615 desc->pixelFormat = Image::OSG_L_PF;
00616 desc->needConversion = false;
00617
00618 desc = &(_formatStrMap["FLOAT"]);
00619 desc->type = Image::OSG_FLOAT32_IMAGEDATA;
00620 desc->bpv = 4;
00621 desc->pixelFormat = Image::OSG_L_PF;
00622 desc->needConversion = false;
00623
00624 desc = &(_formatStrMap["DOUBLE"]);
00625 desc->type = Image::OSG_FLOAT32_IMAGEDATA;
00626 desc->bpv = 8;
00627 desc->pixelFormat = Image::OSG_L_PF;
00628 desc->needConversion = false;
00629 }
00630
00631 }
00632