osg::Node* IconResource::createNodeFromURI( const URI& uri, const osgDB::Options* dbOptions ) const { osg::Node* node = 0L; ReadResult r = uri.readImage( dbOptions ); if ( r.succeeded() ) { OE_INFO << LC << "Loaded " << uri.base() << "(from " << (r.isFromCache()? "cache" : "source") << ")" << std::endl; if ( r.getImage() ) { node = buildIconModel( r.releaseImage() ); } } else // failing that, fall back on the old encoding format.. { StringVector tok; StringTokenizer( *uri, tok, "()" ); if (tok.size() >= 2) return createNodeFromURI( URI(tok[1]), dbOptions ); } return node; }
virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile( file, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; osgDB::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary); if(!istream) return ReadResult::ERROR_IN_READING_FILE; ReadResult rr = readJPGStream(istream); if(rr.validImage()) rr.getImage()->setFileName(file); return rr; }
osg::Node* IconResource::createNodeFromURI( const URI& uri, const osgDB::Options* dbOptions ) const { osg::Node* node = 0L; ReadResult r = uri.readImage( dbOptions ); if ( r.succeeded() ) { if ( r.getImage() ) { node = buildIconModel( r.releaseImage() ); } } else // failing that, fall back on the old encoding format.. { StringVector tok; StringTokenizer( *uri, tok, "()" ); if (tok.size() >= 2) return createNodeFromURI( URI(tok[1]), dbOptions ); } return node; }
ReadResult HTTPClient::doReadImage(const HTTPRequest& request, const osgDB::Options* options, ProgressCallback* callback) { initialize(); ReadResult result; HTTPResponse response = this->doGet(request, options, callback); if (response.isOK()) { osgDB::ReaderWriter* reader = getReader(request.getURL(), response); if (!reader) { result = ReadResult(ReadResult::RESULT_NO_READER); } else { osgDB::ReaderWriter::ReadResult rr = reader->readImage(response.getPartStream(0), options); if ( rr.validImage() ) { result = ReadResult(rr.takeImage()); } else { if ( s_HTTP_DEBUG ) { OE_WARN << LC << reader->className() << " failed to read image from " << request.getURL() << "; message = " << rr.message() << std::endl; } result = ReadResult(ReadResult::RESULT_READER_ERROR); result.setErrorDetail( rr.message() ); } } // last-modified (file time) result.setLastModifiedTime( getCurlFileTime(_curl_handle) ); // Time of query result.setDuration( response.getDuration() ); } else { result = ReadResult( response.isCancelled() ? ReadResult::RESULT_CANCELED : response.getCode() == HTTPResponse::NOT_FOUND ? ReadResult::RESULT_NOT_FOUND : response.getCode() == HTTPResponse::SERVER_ERROR ? ReadResult::RESULT_SERVER_ERROR : response.getCode() == HTTPResponse::NOT_MODIFIED ? ReadResult::RESULT_NOT_MODIFIED : ReadResult::RESULT_UNKNOWN_ERROR ); //If we have an error but it's recoverable, like a server error or timeout then set the callback to retry. if (HTTPClient::isRecoverable( result.code() ) ) { if (callback) { if ( s_HTTP_DEBUG ) { OE_NOTICE << LC << "Error in HTTPClient for " << request.getURL() << " but it's recoverable" << std::endl; } callback->setNeedsRetry( true ); } } } // encode headers result.setMetadata( response.getHeadersAsConfig() ); // set the source name if ( result.getImage() ) result.getImage()->setName( request.getURL() ); return result; }
virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const { ReadResult result = readImage(file, options); if (!result.validImage()) return result; osg::ref_ptr<osgVolume::VolumeTile> tile = new osgVolume::VolumeTile; tile->setVolumeTechnique(new osgVolume::RayTracedTechnique()); osg::ref_ptr<osgVolume::ImageLayer> layer= new osgVolume::ImageLayer(result.getImage()); layer->rescaleToZeroToOneRange(); osgVolume::SwitchProperty* sp = new osgVolume::SwitchProperty; sp->setActiveProperty(0); float alphaFunc = 0.1f; osgVolume::AlphaFuncProperty* ap = new osgVolume::AlphaFuncProperty(alphaFunc); osgVolume::SampleDensityProperty* sd = new osgVolume::SampleDensityProperty(0.005); osgVolume::TransparencyProperty* tp = new osgVolume::TransparencyProperty(1.0); { // Standard osgVolume::CompositeProperty* cp = new osgVolume::CompositeProperty; cp->addProperty(ap); cp->addProperty(sd); cp->addProperty(tp); sp->addProperty(cp); } { // Light osgVolume::CompositeProperty* cp = new osgVolume::CompositeProperty; cp->addProperty(ap); cp->addProperty(sd); cp->addProperty(tp); cp->addProperty(new osgVolume::LightingProperty); sp->addProperty(cp); } { // Isosurface osgVolume::CompositeProperty* cp = new osgVolume::CompositeProperty; cp->addProperty(sd); cp->addProperty(tp); cp->addProperty(new osgVolume::IsoSurfaceProperty(alphaFunc)); sp->addProperty(cp); } { // MaximumIntensityProjection osgVolume::CompositeProperty* cp = new osgVolume::CompositeProperty; cp->addProperty(ap); cp->addProperty(sd); cp->addProperty(tp); cp->addProperty(new osgVolume::MaximumIntensityProjectionProperty); sp->addProperty(cp); } layer->addProperty(sp); tile->setLayer(layer.get()); // get matrix providing size of texels (in mm) osg::RefMatrix* matrix = dynamic_cast<osg::RefMatrix*>(result.getImage()->getUserData()); if (matrix) { osgVolume::Locator* locator = new osgVolume::Locator(*matrix); tile->setLocator(locator); layer->setLocator(locator); // result.getImage()->setUserData(0); osg::notify(osg::NOTICE)<<"Locator "<<*matrix<<std::endl; } else { osg::notify(osg::NOTICE)<<"No Locator found on osg::Image"<<std::endl; } return tile.release(); }
virtual ReadResult readObject (const std::string &file, const osgDB::ReaderWriter::Options* options) const { ReadResult rr = readImage(file, options); if (!rr.validImage()) return rr; bool use_core_video = true; if (options && !options->getPluginStringData("disableCoreVideo").empty()) use_core_video = false; osg::ref_ptr<OSXAVFoundationVideo> video = dynamic_cast<OSXAVFoundationVideo*>(rr.getImage()); if (!video || !use_core_video) return rr; osg::ref_ptr<OSXAVFoundationCoreVideoTexture> texture = new OSXAVFoundationCoreVideoTexture(video); return texture.release(); }
GeoImage ImageLayer::createImageInKeyProfile( const TileKey& key, ProgressCallback* progress, bool forceFallback, bool& out_isFallback ) { GeoImage result; out_isFallback = false; // If the layer is disabled, bail out. if ( !getEnabled() ) { return GeoImage::INVALID; } // Check the max data level, which limits the LOD of available data. if ( _runtimeOptions.maxDataLevel().isSet() && key.getLOD() > _runtimeOptions.maxDataLevel().value() ) { return GeoImage::INVALID; } // Check for a "Minumum level" setting on this layer. If we are before the // min level, just return the empty image. Do not cache empties if ( _runtimeOptions.minLevel().isSet() && key.getLOD() < _runtimeOptions.minLevel().value() ) { return GeoImage( _emptyImage.get(), key.getExtent() ); } // Check for a "Minimum resolution" setting on the layer. If we are before the // min resolution, return the empty image. Do not cache empties. if ( _runtimeOptions.minResolution().isSet() ) { double keyres = key.getExtent().width() / getTileSize(); double keyresInLayerProfile = key.getProfile()->getSRS()->transformUnits(keyres, getProfile()->getSRS()); if ( keyresInLayerProfile > _runtimeOptions.minResolution().value() ) { return GeoImage( _emptyImage.get(), key.getExtent() ); } } OE_DEBUG << LC << "create image for \"" << key.str() << "\", ext= " << key.getExtent().toString() << std::endl; // locate the cache bin for the target profile for this layer: CacheBin* cacheBin = getCacheBin( key.getProfile() ); // validate that we have either a valid tile source, or we're cache-only. if ( ! (getTileSource() || (isCacheOnly() && cacheBin) ) ) { OE_WARN << LC << "Error: layer does not have a valid TileSource, cannot create image " << std::endl; _runtimeOptions.enabled() = false; return GeoImage::INVALID; } // validate the existance of a valid layer profile (unless we're in cache-only mode, in which // case there is no layer profile) if ( !isCacheOnly() && !getProfile() ) { OE_WARN << LC << "Could not establish a valid profile" << std::endl; _runtimeOptions.enabled() = false; return GeoImage::INVALID; } // First, attempt to read from the cache. Since the cached data is stored in the // map profile, we can try this first. if ( cacheBin && getCachePolicy().isCacheReadable() ) { ReadResult r = cacheBin->readImage( key.str(), getCachePolicy().getMinAcceptTime() ); if ( r.succeeded() ) { ImageUtils::normalizeImage( r.getImage() ); return GeoImage( r.releaseImage(), key.getExtent() ); } //else if ( r.code() == ReadResult::RESULT_EXPIRED ) //{ // OE_INFO << LC << getName() << " : " << key.str() << " record expired!" << std::endl; //} } // The data was not in the cache. If we are cache-only, fail sliently if ( isCacheOnly() ) { return GeoImage::INVALID; } // Get an image from the underlying TileSource. result = createImageFromTileSource( key, progress, forceFallback, out_isFallback ); // Normalize the image if necessary if ( result.valid() ) { ImageUtils::normalizeImage( result.getImage() ); } // If we got a result, the cache is valid and we are caching in the map profile, write to the map cache. if (result.valid() && //JB: Removed the check to not write out fallback data. If you have a low resolution base dataset (max lod 3) and a high resolution insert (max lod 22) // then the low res data needs to "fallback" from LOD 4 - 22 so you can display the high res inset. If you don't cache these intermediate tiles then // performance can suffer generating all those fallback tiles, especially if you have to do reprojection or mosaicing. //!out_isFallback && cacheBin && getCachePolicy().isCacheWriteable() ) { if ( key.getExtent() != result.getExtent() ) { OE_INFO << LC << "WARNING! mismatched extents." << std::endl; } cacheBin->write( key.str(), result.getImage() ); //OE_INFO << LC << "WRITING " << key.str() << " to the cache." << std::endl; } if ( result.valid() ) { OE_DEBUG << LC << key.str() << " result OK" << std::endl; } else { OE_DEBUG << LC << key.str() << "result INVALID" << std::endl; } return result; }
ReadResult HTTPClient::doReadImage(const std::string& location, const osgDB::Options* options, ProgressCallback* callback) { initialize(); ReadResult result; HTTPResponse response = this->doGet(location, options, callback); if (response.isOK()) { osgDB::ReaderWriter* reader = getReader(location, response); if (!reader) { OE_WARN << LC << "Can't find an OSG plugin to read "<<location<<std::endl; result = ReadResult(ReadResult::RESULT_NO_READER); } else { osgDB::ReaderWriter::ReadResult rr = reader->readImage(response.getPartStream(0), options); if ( rr.validImage() ) { result = ReadResult(rr.takeImage(), response.getHeadersAsConfig() ); } else { if ( !rr.message().empty() ) { OE_WARN << LC << "HTTP error: " << rr.message() << std::endl; } OE_WARN << LC << reader->className() << " failed to read image from " << location << std::endl; result = ReadResult(ReadResult::RESULT_READER_ERROR); } } } else { result = ReadResult( response.isCancelled() ? ReadResult::RESULT_CANCELED : response.getCode() == HTTPResponse::NOT_FOUND ? ReadResult::RESULT_NOT_FOUND : response.getCode() == HTTPResponse::SERVER_ERROR ? ReadResult::RESULT_SERVER_ERROR : ReadResult::RESULT_UNKNOWN_ERROR ); //If we have an error but it's recoverable, like a server error or timeout then set the callback to retry. if (HTTPClient::isRecoverable( result.code() ) ) { if (callback) { OE_DEBUG << "Error in HTTPClient for " << location << " but it's recoverable" << std::endl; callback->setNeedsRetry( true ); } } } // set the source name if ( result.getImage() ) result.getImage()->setName( location ); return result; }
GeoImage ImageLayer::createImageInKeyProfile(const TileKey& key, ProgressCallback* progress) { GeoImage result; // If the layer is disabled, bail out. if ( !getEnabled() ) { return GeoImage::INVALID; } // Make sure the request is in range. if ( !isKeyInRange(key) ) { return GeoImage::INVALID; } OE_DEBUG << LC << "create image for \"" << key.str() << "\", ext= " << key.getExtent().toString() << std::endl; // Check the layer L2 cache first if ( _memCache.valid() ) { CacheBin* bin = _memCache->getOrCreateBin( key.getProfile()->getFullSignature() ); ReadResult result = bin->readObject(key.str(), 0); if ( result.succeeded() ) return GeoImage(static_cast<osg::Image*>(result.releaseObject()), key.getExtent()); //_memCache->dumpStats(key.getProfile()->getFullSignature()); } // locate the cache bin for the target profile for this layer: CacheBin* cacheBin = getCacheBin( key.getProfile() ); // validate that we have either a valid tile source, or we're cache-only. if ( ! (getTileSource() || (isCacheOnly() && cacheBin) ) ) { OE_WARN << LC << "Error: layer does not have a valid TileSource, cannot create image " << std::endl; _runtimeOptions.enabled() = false; return GeoImage::INVALID; } // validate the existance of a valid layer profile (unless we're in cache-only mode, in which // case there is no layer profile) if ( !isCacheOnly() && !getProfile() ) { OE_WARN << LC << "Could not establish a valid profile" << std::endl; _runtimeOptions.enabled() = false; return GeoImage::INVALID; } // First, attempt to read from the cache. Since the cached data is stored in the // map profile, we can try this first. if ( cacheBin && getCachePolicy().isCacheReadable() ) { ReadResult r = cacheBin->readImage( key.str(), getCachePolicy().getMinAcceptTime() ); if ( r.succeeded() ) { ImageUtils::normalizeImage( r.getImage() ); return GeoImage( r.releaseImage(), key.getExtent() ); } } // The data was not in the cache. If we are cache-only, fail sliently if ( isCacheOnly() ) { return GeoImage::INVALID; } // Get an image from the underlying TileSource. result = createImageFromTileSource( key, progress ); // Normalize the image if necessary if ( result.valid() ) { ImageUtils::normalizeImage( result.getImage() ); } // memory cache first: if ( result.valid() && _memCache.valid() ) { CacheBin* bin = _memCache->getOrCreateBin( key.getProfile()->getFullSignature() ); bin->write(key.str(), result.getImage()); } // If we got a result, the cache is valid and we are caching in the map profile, // write to the map cache. if (result.valid() && cacheBin && getCachePolicy().isCacheWriteable() ) { if ( key.getExtent() != result.getExtent() ) { OE_INFO << LC << "WARNING! mismatched extents." << std::endl; } cacheBin->write( key.str(), result.getImage() ); } if ( result.valid() ) { OE_DEBUG << LC << key.str() << " result OK" << std::endl; } else { OE_DEBUG << LC << key.str() << "result INVALID" << std::endl; } return result; }
Status initialize( const osgDB::Options* dbOptions ) { osg::ref_ptr<osgDB::Options> localOptions = Registry::instance()->cloneOrCreateOptions(dbOptions); CachePolicy::NO_CACHE.apply(localOptions.get()); if ( !getProfile() ) { return Status::Error( "An explicit profile definition is required by the OSG driver." ); } osg::ref_ptr<osg::Image> image; if ( !_options.url()->empty() ) { ReadResult r = _options.url()->readImage( localOptions.get() ); if ( r.succeeded() ) { image = r.getImage(); } } if ( !image.valid() ) { return Status::Error( Stringify() << "Faild to load data from \"" << _options.url()->full() << "\"" ); } // calculate and store the maximum LOD for which to return data if ( image.valid() ) { if ( _options.maxDataLevel().isSet() ) { _maxDataLevel = *_options.maxDataLevel(); } else { int minSpan = osg::minimum( image->s(), image->t() ); int tileSize = _options.tileSize().value(); _maxDataLevel = (int)LOG2((minSpan/tileSize)+1); //OE_NOTICE << "[osgEarth::OSG driver] minSpan=" << minSpan << ", _tileSize=" << tileSize << ", maxDataLevel = " << _maxDataLevel << std::endl; } getDataExtents().push_back( DataExtent(getProfile()->getExtent(), 0, _maxDataLevel) ); bool computeAlpha = (_options.convertLuminanceToRGBA() == true && image->getPixelFormat() == GL_LUMINANCE) || (_options.addAlpha() == true && !ImageUtils::hasAlphaChannel( image.get() ) ); if ( computeAlpha ) { image = makeRGBAandComputeAlpha( image.get() ); } else if ( ImageUtils::hasAlphaChannel( image.get() )) { image = ImageUtils::convertToRGBA8( image.get() ); } else { image = ImageUtils::convertToRGB8( image.get() ); } _image = GeoImage( image.get(), getProfile()->getExtent() ); } _extension = osgDB::getFileExtension( _options.url()->full() ); return STATUS_OK; }