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 #include <stdlib.h>
00042 #include <stdio.h>
00043
00044 #include "OSGConfig.h"
00045
00046 #include <OSGLog.h>
00047 #include <OSGBaseTypes.h>
00048 #include <OSGPathHandler.h>
00049 #include <OSGBaseFunctions.h>
00050 #include <OSGFileSystem.h>
00051
00052 #include "OSGImageFileHandler.h"
00053
00054
00055 OSG_USING_NAMESPACE
00056
00070
00071
00072
00073
00074
00075
00076 ImageFileHandler *ImageFileHandler::_the = 0;
00077 const std::string ImageFileHandler::_fileNameKey("fileName");
00078 const std::string ImageFileHandler::_fullFilePathKey("fullFilePath");
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00093 ImageFileType *ImageFileHandler::getFileType(const char *mimeType,
00094 const char *fileName,
00095 bool validateHeader)
00096 {
00097 IDString suffix;
00098 ImageFileType *type = 0;
00099 std::map<IDString, ImageFileType *>::iterator sI;
00100 const char separator = '.';
00101 int i, l;
00102 std::ifstream fin;
00103 const char *mtPrefix = "image/";
00104 size_t mtLen = strlen(mtPrefix);
00105
00106 if(mimeType && *mimeType)
00107 {
00108 if ( (strlen(mimeType) > mtLen) &&
00109 !strncmp (mimeType, mtPrefix, mtLen) )
00110 mimeType += mtLen;
00111
00112
00113 for(sI = _suffixTypeMap.begin(); sI != _suffixTypeMap.end(); ++sI)
00114 {
00115 if(!stringcasecmp(sI->second->getMimeType(), mimeType))
00116 {
00117 type = sI->second;
00118 break;
00119 }
00120 }
00121 if (!type) {
00122 FWARNING (("Invalid mimeType %s in getFileType()\n", mimeType));
00123 }
00124 }
00125
00126 if(!type && fileName && *fileName)
00127 {
00128
00129 if(!type)
00130 {
00131 l = strlen(fileName);
00132 for(i = l - 1; i >= 0; i--)
00133 {
00134 if(fileName[i] == separator)
00135 break;
00136 }
00137
00138 if(i >= 0)
00139 {
00140 suffix.set(&(fileName[i + 1]));
00141 suffix.toLower();
00142 sI = _suffixTypeMap.find(suffix);
00143 type = (sI == _suffixTypeMap.end()) ? 0 : sI->second;
00144 }
00145 }
00146 }
00147
00148 if(validateHeader)
00149 {
00150
00151 bool implemented = false;
00152 if(fileName && *fileName &&
00153 type != NULL && !type->validateHeader(fileName, implemented))
00154 {
00155 FWARNING (("Found wrong image header trying to autodetect image type!\n"));
00156 for(sI = _suffixTypeMap.begin(); sI != _suffixTypeMap.end(); ++sI)
00157 {
00158 type = sI->second;
00159 if(type != NULL && type->validateHeader(fileName, implemented))
00160 {
00161 if(implemented)
00162 {
00163 FWARNING (("Autodetected '%s' image type!\n", sI->first.str()));
00164 return type;
00165 }
00166 }
00167 }
00168 FWARNING (("Couldn't autodetect image type!\n"));
00169 return NULL;
00170 }
00171 }
00172
00173 return type;
00174 }
00175
00176
00180 ImageFileType *ImageFileHandler::getDefaultType(void)
00181 {
00182 IDString dSuffix("opensg");
00183
00184 std::map<IDString,
00185 ImageFileType *>::iterator sI = _suffixTypeMap.find(dSuffix);
00186
00187
00188 ImageFileType *type = (sI == _suffixTypeMap.end()) ? 0 : sI->second;
00189
00190 if(!type)
00191 {
00192 FFATAL(("Can not find any default (suffix:%s) image handler\n",
00193 dSuffix.str()));
00194 }
00195
00196 return type;
00197 }
00198
00199
00200
00204 Int32 ImageFileHandler::getSuffixList(std::list<const Char8 *> & suffixList,
00205 UInt32 flags)
00206 {
00207 Int32 count = 0;
00208 std::map<IDString, ImageFileType *>::iterator sI;
00209
00210 suffixList.clear();
00211
00212 for ( sI = _suffixTypeMap.begin(); sI != _suffixTypeMap.end(); ++sI)
00213 {
00214 ImageFileType *type = sI->second;
00215 if(type->getFlags() & flags)
00216 {
00217 suffixList.push_back(sI->first.str());
00218 count++;
00219 }
00220 }
00221
00222 return count;
00223 }
00224
00225
00232 ImagePtr ImageFileHandler::read(const char *fileName, const char *mimeType)
00233 {
00234 ImagePtr image = Image::create();
00235
00236 if(read(image, fileName, mimeType) == false)
00237 {
00238 subRefCP(image);
00239 image = NullFC;
00240 }
00241 return image;
00242 }
00243
00244
00252 bool ImageFileHandler::read(ImagePtr &image, const char *fileName,
00253 const char *mimeType)
00254 {
00255 bool retCode = false;
00256 std::string fullFilePath;
00257
00258 if( _pPathHandler != NULL )
00259 {
00260 fullFilePath = _pPathHandler->findFile(fileName);
00261 }
00262 else
00263 {
00264 fullFilePath = fileName;
00265 }
00266
00267 if(fullFilePath.empty())
00268 {
00269 SWARNING << "couldn't find image file " << fileName << std::endl;
00270 return false;
00271 }
00272
00273 ImageFileType *type = getFileType(mimeType, fullFilePath.c_str(), true);
00274
00275 if(type)
00276 {
00277 FDEBUG(("try to image read %s as %s\n",
00278 fullFilePath.c_str(),
00279 type->getMimeType()));
00280
00281 retCode = type->read(image, fullFilePath.c_str());
00282
00283 if(retCode)
00284 {
00285 FDEBUG(("image: %dx%d\n", image->getWidth(), image->getHeight()));
00286 image->setAttachmentField(_fileNameKey, fileName);
00287 image->setAttachmentField(_fullFilePathKey, fullFilePath);
00288 }
00289 else
00290 {
00291 SWARNING << "could not read " << fullFilePath << std::endl;
00292 }
00293 }
00294 else
00295 {
00296 SWARNING << "could not read " << fullFilePath
00297 << "; unknown image format" << std::endl;
00298 }
00299
00300 return retCode;
00301 }
00302
00303
00311 bool ImageFileHandler::write(const ImagePtr &image, const char *fileName,
00312 const char *mimeType)
00313 {
00314 bool retCode = false;
00315 ImageFileType *type;
00316 const std::string *fNAttachment;
00317
00318 if (!fileName && (fNAttachment = image->findAttachmentField(_fileNameKey)))
00319 fileName = fNAttachment->c_str();
00320
00321 if ((type = getFileType(mimeType, fileName)))
00322 {
00323 SINFO << "try to write " << fileName << " as "
00324 << type->getMimeType() << std::endl;
00325 retCode = type->write(image, fileName);
00326 }
00327 else
00328 {
00329 SWARNING << "can't write " << fileName
00330 << "; unknown image format" << std::endl;
00331 }
00332
00333 return retCode;
00334 }
00335
00336
00340 PathHandler* ImageFileHandler::getPathHandler(void)
00341 {
00342 return _pPathHandler;
00343 }
00344
00345
00349 void ImageFileHandler::setPathHandler(PathHandler *pPathHandler)
00350 {
00351 _pPathHandler = pPathHandler;
00352 }
00353
00354
00362 UInt64 ImageFileHandler::restore(ImagePtr &image, const UChar8 *buffer,
00363 Int32 memSize)
00364 {
00365 return ImageFileType::restore(image, buffer, memSize);
00366 }
00367
00368
00376 UInt64 ImageFileHandler::store(const ImagePtr &image, const char *mimeType,
00377 UChar8 *buffer, Int32 memSize)
00378 {
00379 ImageFileType *type;
00380
00381 type = mimeType ? getFileType(mimeType) : getDefaultType();
00382
00383 return type->store(image, buffer, memSize);
00384 }
00385
00386
00396 UChar8 *ImageFileHandler::store(const ImagePtr &image, UInt64 &memSize,
00397 const char *mimeType)
00398 {
00399 ImageFileType *type = 0;
00400 UChar8 *mem = 0;
00401
00402 type = mimeType ? getFileType(mimeType) : getDefaultType();
00403 memSize = type->maxBufferSize(image);
00404
00405 if(memSize)
00406 {
00407 mem = new UChar8[size_t(memSize)];
00408 memSize = type->store(image, mem, Int32(memSize));
00409 }
00410 else
00411 {
00412 FFATAL(("Can not store the image as %s\n", type->getMimeType()));
00413 }
00414
00415 return mem;
00416 }
00417
00418
00422 void ImageFileHandler::dump(void)
00423 {
00424 std::map<IDString, ImageFileType *>::iterator sI;
00425
00426 for(sI = _suffixTypeMap.begin(); sI != _suffixTypeMap.end(); sI++)
00427 {
00428 FLOG (( "Image suffix: %s, mimeType: %s\n",
00429 sI->first.str(), sI->second->getMimeType() ));
00430 }
00431 }
00432
00433
00437 bool ImageFileHandler::addImageFileType(ImageFileType &fileType)
00438 {
00439 bool retCode = false;
00440 std::list<IDString >::const_iterator sI;
00441 std::map <IDString, ImageFileType *>::iterator smI;
00442 IDString suffix;
00443
00444 if(!_the)
00445 _the = new ImageFileHandler;
00446
00447 for( sI = fileType.getSuffixList().begin();
00448 sI != fileType.getSuffixList().end();
00449 ++sI)
00450 {
00451 suffix.set(sI->str());
00452 suffix.toLower();
00453 smI = _the->_suffixTypeMap.find(suffix);
00454 if(smI != _the->_suffixTypeMap.end())
00455 {
00456 SWARNING << "Can't add an image file type with suffix "
00457 << suffix << " a second time" << std::endl;
00458 }
00459 else
00460 {
00461 _the->_suffixTypeMap[suffix] = &fileType;
00462 retCode = true;
00463 }
00464 }
00465
00466 return retCode;
00467 }
00468
00469
00473 ImageFileHandler::ImageFileHandler(void)
00474 {
00475 _pPathHandler = NULL;
00476 return;
00477 }
00478
00479
00483 ImageFileHandler::ImageFileHandler(const ImageFileHandler &)
00484 {
00485 FFATAL (("Run Copy Constructor on Singleton ImageFileHandler !\n"));
00486
00487 _pPathHandler = NULL;
00488 return;
00489 }
00490
00491
00495 ImageFileHandler::~ImageFileHandler(void)
00496 {
00497 return;
00498 }
00499
00500
00504 ImageFileHandler & ImageFileHandler::the(void)
00505 {
00506 return *_the;
00507 }