From fd51518d9214f8e152e16ae46392501b95bab28a Mon Sep 17 00:00:00 2001 From: Thomas Geymayer Date: Thu, 20 Mar 2014 01:44:31 +0100 Subject: [PATCH] CanvasImage: improve fetching from http and add mime detection. --- simgear/canvas/elements/CanvasImage.cxx | 57 +++++++++++++++++-------- simgear/canvas/elements/CanvasImage.hxx | 4 ++ simgear/io/HTTPRequest.cxx | 10 +++++ simgear/io/HTTPRequest.hxx | 2 + 4 files changed, 56 insertions(+), 17 deletions(-) diff --git a/simgear/canvas/elements/CanvasImage.cxx b/simgear/canvas/elements/CanvasImage.cxx index a8eb4109..c201e589 100644 --- a/simgear/canvas/elements/CanvasImage.cxx +++ b/simgear/canvas/elements/CanvasImage.cxx @@ -661,31 +661,54 @@ namespace canvas { if( req->responseCode() != 200 ) { - SG_LOG( SG_GL, - SG_WARN, - "canvas::Image: failed to download '" << req->url() << "': " - << req->responseReason() ); + SG_LOG(SG_IO, SG_WARN, "failed to download '" << req->url() << "': " + << req->responseReason()); return; } - std::string ext = SGPath(req->path()).extension(); - SG_LOG(SG_GL, SG_INFO, "canvas::Image: received " << req->url()); + const std::string ext = SGPath(req->path()).extension(), + mime = req->responseMime(); - osgDB::ReaderWriter* rw = - osgDB::Registry::instance()->getReaderWriterForExtension(ext); + SG_LOG(SG_IO, SG_INFO, "received " << req->url() << + " (ext=" << ext << ", MIME=" << mime << ")"); - std::istringstream img_data( - static_cast(req)->responseBody() - ); + const std::string& img_data = + static_cast(req)->responseBody(); + osgDB::Registry* reg = osgDB::Registry::instance(); + + // First try to detect image type by extension + osgDB::ReaderWriter* rw = reg->getReaderWriterForExtension(ext); + if( rw && loadImage(*rw, img_data, *req, "extension") ) + return; + + // Now try with MIME type + rw = reg->getReaderWriterForMimeType(req->responseMime()); + if( rw && loadImage(*rw, img_data, *req, "MIME type") ) + return; + + SG_LOG(SG_IO, SG_WARN, "unable to read image '" << req->url() << "'"); + } - osgDB::ReaderWriter::ReadResult result = rw->readImage(img_data); + //---------------------------------------------------------------------------- + bool Image::loadImage( osgDB::ReaderWriter& reader, + const std::string& data, + HTTP::Request& request, + const std::string& type ) + { + SG_LOG(SG_IO, SG_DEBUG, "use image reader detected by " << type); + + std::istringstream data_strm(data); + osgDB::ReaderWriter::ReadResult result = reader.readImage(data_strm); if( result.success() ) + { setImage( result.takeImage() ); - else - SG_LOG( SG_GL, - SG_WARN, - "canvas::Image: failed to read image '" << req->url() << "': " - << result.message() ); + return true; + } + + SG_LOG(SG_IO, SG_WARN, "failed to read image '" << request.url() << "': " + << result.message()); + + return false; } } // namespace canvas diff --git a/simgear/canvas/elements/CanvasImage.hxx b/simgear/canvas/elements/CanvasImage.hxx index 6d16e8b3..c9e3c081 100644 --- a/simgear/canvas/elements/CanvasImage.hxx +++ b/simgear/canvas/elements/CanvasImage.hxx @@ -105,6 +105,10 @@ namespace canvas void setQuadUV(size_t index, const SGVec2f& tl, const SGVec2f& br); void handleImageLoadDone(HTTP::Request*); + bool loadImage( osgDB::ReaderWriter& reader, + const std::string& data, + HTTP::Request& request, + const std::string& type ); osg::ref_ptr _texture; // TODO optionally forward events to canvas diff --git a/simgear/io/HTTPRequest.cxx b/simgear/io/HTTPRequest.cxx index 46c64d5d..535ec402 100644 --- a/simgear/io/HTTPRequest.cxx +++ b/simgear/io/HTTPRequest.cxx @@ -272,6 +272,16 @@ std::string Request::hostAndPort() const return u.substr(schemeEnd + 3, hostEnd - (schemeEnd + 3)); } +//------------------------------------------------------------------------------ +std::string Request::responseMime() const +{ + std::string content_type = _responseHeaders.get("content-type"); + if( content_type.empty() ) + return "application/octet-stream"; + + return content_type.substr(0, content_type.find(';')); +} + //------------------------------------------------------------------------------ void Request::setResponseLength(unsigned int l) { diff --git a/simgear/io/HTTPRequest.hxx b/simgear/io/HTTPRequest.hxx index e12e6d8d..ef101b3f 100644 --- a/simgear/io/HTTPRequest.hxx +++ b/simgear/io/HTTPRequest.hxx @@ -118,6 +118,8 @@ public: StringMap const& responseHeaders() const { return _responseHeaders; } + std::string responseMime() const; + virtual int responseCode() const { return _responseStatus; } -- 2.39.2