Go to the documentation of this file.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 #include <rve_render_server/texture.h>
00031 #include <resource_retriever/retriever.h>
00032 
00033 #include <sensor_msgs/Image.h>
00034 #include <sensor_msgs/image_encodings.h>
00035 
00036 #include <OGRE/OgreTextureManager.h>
00037 
00038 #include <boost/filesystem.hpp>
00039 
00040 namespace fs = boost::filesystem;
00041 
00042 namespace rve_render_server
00043 {
00044 
00045 Texture::Texture(const rve_common::UUID& id, uint32_t num_mip_maps)
00046 : id_(id)
00047 , num_mip_maps_(num_mip_maps)
00048 {
00049   int usage = Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE|Ogre::TU_AUTOMIPMAP;
00050   Ogre::PixelFormat format = Ogre::TextureManager::getSingleton().getNativeFormat(Ogre::TEX_TYPE_2D, Ogre::PF_BYTE_RGBA, usage);
00051   texture_ = Ogre::TextureManager::getSingleton().createManual(getID().toString(), ROS_PACKAGE_NAME, Ogre::TEX_TYPE_2D, 1, 1, num_mip_maps, format, usage);
00052 }
00053 
00054 Texture::~Texture()
00055 {
00056   Ogre::TextureManager::getSingleton().remove(id_.toString());
00057 }
00058 
00059 void Texture::setImage(const sensor_msgs::Image& image)
00060 {
00061   if (image.data.empty())
00062   {
00063     throw std::runtime_error("Image has no data");
00064   }
00065 
00066   Ogre::PixelFormat format = Ogre::PF_R8G8B8;
00067   Ogre::Image ogre_image;
00068   std::vector<uint8_t> buffer;
00069   void* data_ptr = (void*)&image.data[0];
00070   uint32_t data_size = image.data.size();
00071   if (image.encoding == sensor_msgs::image_encodings::RGB8)
00072   {
00073     format = Ogre::PF_BYTE_RGB;
00074   }
00075   else if (image.encoding == sensor_msgs::image_encodings::RGBA8)
00076   {
00077     format = Ogre::PF_BYTE_RGBA;
00078   }
00079   else if (image.encoding == sensor_msgs::image_encodings::TYPE_8UC4 ||
00080            image.encoding == sensor_msgs::image_encodings::TYPE_8SC4 ||
00081            image.encoding == sensor_msgs::image_encodings::BGRA8)
00082   {
00083     format = Ogre::PF_BYTE_BGRA;
00084   }
00085   else if (image.encoding == sensor_msgs::image_encodings::TYPE_8UC3 ||
00086            image.encoding == sensor_msgs::image_encodings::TYPE_8SC3 ||
00087            image.encoding == sensor_msgs::image_encodings::BGR8)
00088   {
00089     format = Ogre::PF_BYTE_BGR;
00090   }
00091   else if (image.encoding == sensor_msgs::image_encodings::TYPE_8UC1 ||
00092            image.encoding == sensor_msgs::image_encodings::TYPE_8SC1 ||
00093            image.encoding == sensor_msgs::image_encodings::MONO8)
00094   {
00095     format = Ogre::PF_BYTE_L;
00096   }
00097   else if (image.encoding == sensor_msgs::image_encodings::TYPE_16UC1 ||
00098            image.encoding == sensor_msgs::image_encodings::TYPE_16SC1 ||
00099            image.encoding == sensor_msgs::image_encodings::MONO16)
00100   {
00101     format = Ogre::PF_BYTE_L;
00102 
00103     
00104     buffer.resize(image.data.size() / 2);
00105     data_size = buffer.size();
00106     data_ptr = (void*)&buffer[0];
00107     for (size_t i = 0; i < data_size; ++i)
00108     {
00109       uint16_t s = image.data[2*i] << 8 | image.data[2*i + 1];
00110       float val = (float)s / std::numeric_limits<uint16_t>::max();
00111       buffer[i] = val * 255;
00112     }
00113   }
00114   else if (image.encoding.find("bayer") == 0)
00115   {
00116     format = Ogre::PF_BYTE_L;
00117   }
00118   else
00119   {
00120     throw std::runtime_error("Unsupported image encoding [" + image.encoding + "]");
00121   }
00122 
00123   
00124 
00125   Ogre::DataStreamPtr pixel_stream;
00126   pixel_stream.bind(new Ogre::MemoryDataStream(data_ptr, data_size));
00127   ogre_image.loadRawData(pixel_stream, image.width, image.height, format);
00128 
00129   texture_->unload();
00130   texture_->loadImage(ogre_image);
00131 }
00132 
00133 void Texture::loadFromFile(const std::string& file)
00134 {
00135   resource_retriever::Retriever retriever;
00136   resource_retriever::MemoryResource res = retriever.get(file);
00137 
00138   if (res.size == 0)
00139   {
00140     throw std::runtime_error("Zero-length file [" + file + "]");
00141   }
00142 
00143   Ogre::DataStreamPtr pixel_stream;
00144   pixel_stream.bind(new Ogre::MemoryDataStream(res.data.get(), res.size));
00145   Ogre::Image image;
00146   image.load(pixel_stream, fs::extension(file).substr(1));
00147 
00148   texture_->unload();
00149   texture_->loadImage(image);
00150 }
00151 
00152 }