]> git.mxchange.org Git - simgear.git/commitdiff
CanvasImage: improve fetching from http and add mime detection.
authorThomas Geymayer <tomgey@gmail.com>
Thu, 20 Mar 2014 00:44:31 +0000 (01:44 +0100)
committerThomas Geymayer <tomgey@gmail.com>
Thu, 20 Mar 2014 00:44:31 +0000 (01:44 +0100)
simgear/canvas/elements/CanvasImage.cxx
simgear/canvas/elements/CanvasImage.hxx
simgear/io/HTTPRequest.cxx
simgear/io/HTTPRequest.hxx

index a8eb410982f2b649bfb03a3ea98f9f1ad734ed03..c201e5890d5ca9c29462085377fe80f3c0090600 100644 (file)
@@ -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<HTTP::MemoryRequest*>(req)->responseBody()
-    );
+    const std::string& img_data =
+      static_cast<HTTP::MemoryRequest*>(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
index 6d16e8b3d3ff38ecc9455facdec87124f921896b..c9e3c081289f5ced3c7f8853ad276833e5074dde 100644 (file)
@@ -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<osg::Texture2D> _texture;
       // TODO optionally forward events to canvas
index 46c64d5df84654c3698df0f72b59fab81ecd2de0..535ec402da8fa9c043ded3de7f9f7e0d0238fa63 100644 (file)
@@ -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)
 {
index e12e6d8d9c2d16b13caa35b332b7c1cc118dbb7e..ef101b3f3e9fb8b26e55b3ac49bcea1cb17bdbac 100644 (file)
@@ -118,6 +118,8 @@ public:
     StringMap const& responseHeaders() const
         { return _responseHeaders; }
 
+    std::string responseMime() const;
+
     virtual int responseCode() const
         { return _responseStatus; }