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 #include <OSGConfig.h>
00040 #include <iostream>
00041 #include <fstream>
00042
00043
00044 #include "OSGImageFileType.h"
00045 #include "OSGImageFileHandler.h"
00046 #include "OSGImageGenericAtt.h"
00047 #include "OSGLog.h"
00048 #include "OSGBaseFunctions.h"
00049
00050 OSG_USING_NAMESPACE
00051
00052
00058
00062 bool ImageFileType::Head::netToHost(void)
00063 {
00064 pixelFormat = osgntohs(pixelFormat);
00065 width = osgntohs(width);
00066 height = osgntohs(height);
00067 depth = osgntohs(depth);
00068 mipmapCount = osgntohs(mipmapCount);
00069 frameCount = osgntohs(frameCount);
00070 frameDelay = osgntohs(frameDelay);
00071 sideCount = osgntohs(sideCount);
00072 dataType = osgntohs(dataType);
00073 _reserved3 = 0;
00074 _reserved4 = 0;
00075 attachmentSize = osgntohs(attachmentSize);
00076
00077 return true;
00078 }
00079
00080
00081
00085 bool ImageFileType::Head::hostToNet(void)
00086 {
00087 pixelFormat = osghtons(pixelFormat);
00088 width = osghtons(width);
00089 height = osghtons(height);
00090 depth = osghtons(depth);
00091 mipmapCount = osghtons(mipmapCount);
00092 frameCount = osghtons(frameCount);
00093 frameDelay = osghtons(frameDelay);
00094 sideCount = osghtons(sideCount);
00095 dataType = osghtons(dataType);
00096 _reserved3 = 0;
00097 _reserved4 = 0;
00098 attachmentSize = osghtons(attachmentSize);
00099
00100 return true;
00101 }
00102
00103
00107 const Char8 *ImageFileType::getMimeType(void) const
00108 {
00109 return _mimeType.str();
00110 }
00111
00112
00117 UInt32 ImageFileType::getFlags(void) const
00118 {
00119 return _flags;
00120 }
00121
00122
00123
00124 const Char8 *ImageFileType::getOptions(void)
00125 {
00126 return _options.c_str();
00127 }
00128
00129
00130
00134 const std::list<IDString> &ImageFileType::getSuffixList(void) const
00135 {
00136 return _suffixList;
00137 }
00138
00139
00140
00141 bool ImageFileType::read(ImagePtr &image, const Char8 *fileName)
00142 {
00143 std::ifstream is(fileName, std::ios::binary);
00144 if (is.good() == false)
00145 return false;
00146 return read(image, is, std::string());
00147 }
00148
00149
00150
00151 bool ImageFileType::write(const ImagePtr &image, const Char8 *fileName)
00152 {
00153 std::ofstream os(fileName, std::ios::binary);
00154 if (os.good() == false)
00155 return false;
00156 return write(image, os, std::string());
00157 }
00158
00159
00160
00161 bool ImageFileType::validateHeader( const Char8 *fileName, bool &implemented)
00162 {
00163 implemented = false;
00164 return true;
00165 }
00166
00167
00172 bool ImageFileType::read(ImagePtr &image, std::istream &is, const std::string &mimetype)
00173 {
00174 SWARNING << getMimeType()
00175 << " read from stream is not implemented"
00176 << endLog;
00177 return false;
00178 }
00179
00180
00185 bool ImageFileType::write(const ImagePtr &image, std::ostream &os, const std::string &mimetype)
00186 {
00187 SWARNING << getMimeType()
00188 << " write to stream is not implemented"
00189 << endLog;
00190 return false;
00191 }
00192
00193
00199 std::string ImageFileType::determineMimetypeFromStream(std::istream &is)
00200 {
00201 return std::string();
00202 }
00203
00204
00209 ImageFileType::ImageFileType( const char *mimeType,
00210 const Char8 *suffixArray[],
00211 UInt16 suffixByteCount,
00212 UInt32 flags)
00213 {
00214 Int32 suffixCount = suffixByteCount / sizeof(const Char8 *);
00215 Int32 i = 0;
00216 std::list<IDString>::iterator sI;
00217
00218 if (!mimeType) {
00219 FFATAL (("ImageFileType without valid mimeType\n"));
00220 }
00221 _mimeType.set(mimeType);
00222
00223 _suffixList.resize(suffixCount);
00224 for(sI = _suffixList.begin(); sI != _suffixList.end(); sI++)
00225 {
00226 sI->set(suffixArray[i++]);
00227 SINFO << "add image suffix: " << *sI << endLog;
00228 }
00229
00230 _flags = flags;
00231
00232 ImageFileHandler::addImageFileType(*this);
00233 }
00234
00235
00239 ImageFileType::~ImageFileType(void) {}
00240
00241
00242
00243 void ImageFileType::setOptions(const Char8 *options)
00244 {
00245 _options = options;
00246 }
00247
00248
00253 UInt64 ImageFileType::restoreData( ImagePtr &,
00254 const UChar8 *OSG_CHECK_ARG(buffer ),
00255 Int32 OSG_CHECK_ARG(memSize))
00256 {
00257 FWARNING(("ImageXFileType::restoreData() not impl. for mimeType %s\n",
00258 getMimeType()));
00259
00260 return 0;
00261 }
00262
00263
00268 UInt64 ImageFileType::storeData(const ImagePtr &,
00269 UChar8 *OSG_CHECK_ARG(buffer ),
00270 Int32 OSG_CHECK_ARG(memSize))
00271 {
00272 FWARNING(("ImageXFileType::storeData() not impl. for mimeType %s\n",
00273 getMimeType()));
00274
00275 return 0;
00276 }
00277
00278
00283 UInt64 ImageFileType::restore( ImagePtr &image,
00284 const UChar8 *buffer, Int32 memSize)
00285 {
00286 unsigned long imageSize, headSize = sizeof(Head);
00287 unsigned long size = 0, attachmentSize;
00288 Head head;
00289 const UChar8 *data = buffer ? (buffer + headSize) : 0;
00290 ImageFileType *type;
00291 std::string mimeType;
00292 Image::Type dataType;
00293
00294 if ((image != osg::NullFC) && buffer && (memSize >= headSize)) {
00295
00296
00297
00298 memcpy(&head,buffer,sizeof(Head));
00299 head.netToHost();
00300 mimeType = ImageFileHandler::the().determineMimetypeFromSuffix(head.suffix);
00301
00302 if((type = ImageFileHandler::the().getFileType(mimeType.c_str(), 0)))
00303 {
00304 if (head.dataType)
00305 dataType = Image::Type(head.dataType);
00306 else
00307 dataType = Image::OSG_UINT8_IMAGEDATA;
00308
00309 image->set(Image::PixelFormat(head.pixelFormat), head.width,
00310 head.height, head.depth, head.mipmapCount,
00311 head.frameCount, float(head.frameDelay) / 1000.0, 0,
00312 dataType,true,head.sideCount );
00313 imageSize = static_cast<unsigned long>(
00314 type->restoreData(image, data, memSize - headSize));
00315 attachmentSize = 0;
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 size = headSize + imageSize + attachmentSize;
00340
00341 FDEBUG (( "Restore image data: %lu (%lu/%lu/%lu)\n",
00342 size, headSize, imageSize, attachmentSize ));
00343
00344 }
00345 else
00346 {
00347 imageSize = 0;
00348 FWARNING(("Can not restore image data, invalid mimeType: %s\n",
00349 mimeType.empty() == false ? mimeType.c_str() : "Unknown"));
00350 }
00351
00352
00353 }
00354
00355 return size;
00356 }
00357
00358
00364 UInt64 ImageFileType::store(const ImagePtr &image, const char *mimeType,
00365 UChar8 *buffer, Int32 memSize)
00366 {
00367 ImageFileType *type = ImageFileHandler::the().getFileType(mimeType);
00368
00369 return type ? type->store(image, buffer, memSize) : 0;
00370 }
00371
00372
00378 UInt64 ImageFileType::store(const ImagePtr &image,
00379 UChar8 *buffer, Int32 memSize)
00380 {
00381 Head *head;
00382 unsigned long dataSize = 0, headSize = sizeof(Head);
00383 unsigned long attachmentSize;
00384 UChar8 *dest;
00385 const UChar8 *src = image->getData();
00386 std::map<std::string, std::string>::const_iterator aI;
00387 std::string value;
00388
00389 attachmentSize = 0;
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 if (buffer)
00420 {
00421 head = (Head *)buffer;
00422
00423 head->pixelFormat = image->getPixelFormat();
00424 head->width = image->getWidth();
00425 head->height = image->getHeight();
00426 head->depth = image->getDepth();
00427 head->mipmapCount = image->getMipMapCount();
00428 head->frameCount = image->getFrameCount();
00429 head->frameDelay = short(image->getFrameDelay() * 1000.0);
00430 head->sideCount = image->getSideCount();
00431 head->dataType = image->getDataType();
00432 head->attachmentSize = static_cast<unsigned short>(attachmentSize);
00433 head->hostToNet();
00434
00435 strcpy(head->suffix, _suffixList.front().str());
00436
00437 dest = (UChar8 *) (buffer + headSize);
00438
00439 if (src)
00440 dataSize = static_cast<unsigned long>(
00441 storeData(image, dest, memSize - headSize));
00442
00443 dest = (UChar8 *) (buffer + headSize + dataSize);
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 FDEBUG (( "Store image data: %lu (%lu/%lu/%lu)\n",
00474 headSize + dataSize + attachmentSize, headSize, dataSize,
00475 attachmentSize ));
00476 }
00477 else {
00478 FFATAL (("Invalid buffer in ImageFileType::store()\n"));
00479 }
00480
00481 return (headSize + dataSize + attachmentSize);
00482
00483 }
00484
00485
00490 UInt64 ImageFileType::maxBufferSize(const ImagePtr &image)
00491 {
00492 std::string value;
00493 unsigned long size, attachmentSize;
00494 unsigned long imageSize = image->getSize(), headSize = sizeof(Head);
00495
00496 std::map<std::string, std::string>::const_iterator aI;
00497
00498 attachmentSize = 0;
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 size = headSize + imageSize + attachmentSize;
00526
00527 FINFO (( "ImageFileType::maxBufferSize(): %lu (%lu/%lu/%lu)\n",
00528 size, headSize, imageSize, attachmentSize ));
00529
00530 return size;
00531 }
00532
00533
00537 void ImageFileType::dump(void)
00538 {
00539 std::list<IDString>::iterator sI;
00540
00541 SLOG << getMimeType();
00542
00543 if(_suffixList.empty())
00544 {
00545 SLOG << ": Suffix: ";
00546 for(sI = _suffixList.begin(); sI != _suffixList.end(); sI++)
00547 {
00548 Log().stream(OSG::LOG_DEBUG) << sI->str() << " ";
00549 }
00550 }
00551
00552 std::cerr << std::endl;
00553 }