• [原][osg]分析JPEG插件的读取写入


    本文为了分析osg插件的内部实现,举了一个ReaderWriterJPEG插件的例子进行分析,本文代码全为C++代码

    osg通过插件的方式读取写入文件

    用osg的jpeg插件举例

    文件OSGsrcosgPluginsjpegReaderWriterJPEG.cpp 中定义了类:

    class ReaderWriterJPEG : public osgDB::ReaderWriter

    一、插件读取部分

    在virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const函数中

    1.首先将文件以二进制流的方式读取进来

    osgDB::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary);

    2.然后再将二进制流通过算法解析成读取结果:ReadResult

    ReadResult rr = readJPGStream(istream);

    那这个ReadResult是个什么东西,这个要怎么用,我们来分析一下这个类

    osgDB/ReaderWriter 头文件中

    声明并定义了osgDB::ReaderWriter类

    在这个类中声明并定义了ReadResult类

     1 class OSGDB_EXPORT ReadResult
     2         {
     3             public:
     4 
     5                 enum ReadStatus
     6                 {
     7                     NOT_IMPLEMENTED, //!< read*() method not implemented in concrete ReaderWriter.
     8                     FILE_NOT_HANDLED, //!< File is not appropriate for this file reader, due to some incompatibility, but *not* a read error.
     9                     FILE_NOT_FOUND, //!< File could not be found or could not be read.
    10                     ERROR_IN_READING_FILE, //!< File found, loaded, but an error was encountered during processing.
    11                     FILE_LOADED, //!< File successfully found, loaded, and converted into osg.
    12                     FILE_LOADED_FROM_CACHE, //!< File found in cache and returned.
    13                     FILE_REQUESTED, //!< Asynchronous file read has been requested, but returning immediately, keep polling plugin until file read has been completed.
    14                     INSUFFICIENT_MEMORY_TO_LOAD //!< File found but not loaded because estimated required memory surpasses available memory.
    15                 };
    16 
    17                 ReadResult(ReadStatus status=FILE_NOT_HANDLED):_status(status) {}
    18                 ReadResult(const std::string& m):_status(ERROR_IN_READING_FILE),_message(m) {}
    19 
    20                 ReadResult(osg::Object* obj, ReadStatus status=FILE_LOADED):_status(status),_object(obj) {}
    21 
    22                 template<class T>
    23                 ReadResult(const osg::ref_ptr<T>& obj, ReadStatus status=FILE_LOADED):_status(status),_object(obj.get()) {}
    24 
    25                 ReadResult(const ReadResult& rr):_status(rr._status),_message(rr._message),_object(rr._object) {}
    26                 ReadResult& operator = (const ReadResult& rr) { if (this==&rr) return *this; _status=rr._status; _message=rr._message;_object=rr._object; return *this; }
    27 
    28                 bool operator < (const ReadResult& rhs) const { return _status < rhs._status; }
    29 
    30                 osg::Object* getObject();
    31                 osg::Image* getImage();
    32                 osg::HeightField* getHeightField();
    33                 osg::Node* getNode();
    34                 osgDB::Archive* getArchive();
    35                 osg::Shader* getShader();
    36                 osg::Script* getScript();
    37 
    38                 bool validObject() { return _object.valid(); }
    39                 bool validImage() { return getImage()!=0; }
    40                 bool validHeightField() { return getHeightField()!=0; }
    41                 bool validNode() { return getNode()!=0; }
    42                 bool validArchive() { return getArchive()!=0; }
    43                 bool validShader() { return getShader()!=0; }
    44                 bool validScript() { return getScript()!=0; }
    45 
    46                 osg::Object* takeObject();
    47                 osg::Image* takeImage();
    48                 osg::HeightField* takeHeightField();
    49                 osg::Node* takeNode();
    50                 osgDB::Archive* takeArchive();
    51                 osg::Shader* takeShader();
    52                 osg::Script* takeScript();
    53 
    54                 std::string& message() { return _message; }
    55                 const std::string& message() const { return _message; }
    56 
    57                 ReadStatus status() const { return _status; }
    58                 bool success() const { return _status==FILE_LOADED || _status==FILE_LOADED_FROM_CACHE ; }
    59                 bool loadedFromCache() const { return _status==FILE_LOADED_FROM_CACHE; }
    60                 bool error() const { return _status==ERROR_IN_READING_FILE; }
    61                 bool notHandled() const { return _status==FILE_NOT_HANDLED || _status==NOT_IMPLEMENTED; }
    62                 bool notFound() const { return _status==FILE_NOT_FOUND; }
    63                 bool notEnoughMemory() const { return _status==INSUFFICIENT_MEMORY_TO_LOAD; }
    64 
    65             protected:
    66 
    67                 ReadStatus                  _status;
    68                 std::string                 _message;
    69                 osg::ref_ptr<osg::Object>   _object;
    70 
    71         };

    这个ReadResult支持osg读取多种类型的数据,有7种类型:目标物、图片、高度场、节点、文档、着色器、脚本。

    1                 osg::Object* getObject();
    2                 osg::Image* getImage();
    3                 osg::HeightField* getHeightField();
    4                 osg::Node* getNode();
    5                 osgDB::Archive* getArchive();
    6                 osg::Shader* getShader();
    7                 osg::Script* getScript();

    接口定义:

    1 osg::Object* ReaderWriter::ReadResult::getObject() { return _object.get(); }
    2 osg::Image* ReaderWriter::ReadResult::getImage() { return dynamic_cast<osg::Image*>(_object.get()); }
    3 osg::HeightField* ReaderWriter::ReadResult::getHeightField() { return dynamic_cast<osg::HeightField*>(_object.get()); }
    4 osg::Node* ReaderWriter::ReadResult::getNode() { return dynamic_cast<osg::Node*>(_object.get()); }
    5 osgDB::Archive* ReaderWriter::ReadResult::getArchive() { return dynamic_cast<osgDB::Archive*>(_object.get()); }
    6 osg::Shader* ReaderWriter::ReadResult::getShader() { return dynamic_cast<osg::Shader*>(_object.get()); }
    7 osg::Script* ReaderWriter::ReadResult::getScript() { return dynamic_cast<osg::Script*>(_object.get()); }
    View Code

    通过接口定义可以看到这里所有类型都是由osg::Object指针强转过来的,所以ReadResult即可支持了需要读取的所有类型。

    读取的函数readJPGStream需要实现的其实就是将数据流std::ifstream转成对应的osg::Image数据。

    二、插件写入部分

     在 virtual WriteResult writeImage(const osg::Image &img,const std::string& fileName, const osgDB::ReaderWriter::Options *options) const

    1.先将文件输出流打开

    osgDB::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary);

    2.将数据写入数据流

    WriteResult::WriteStatus ws = write_JPEG_file(fout, *(tmp_img.get()), getQuality(options));

    这个写入结果WriteResult就简单很多,它不关心写入的数据类型,只关注写入成功与否,这里不用去仔细分析。

    这里的write_JPEG_file函数就完成了,从osg::Image到数据流std::ofstream的转换

    备注:

    osgDB下面的两个流就是调用std的fstream

    class OSGDB_EXPORT ifstream : public std::ifstream

    class OSGDB_EXPORT ofstream : public std::ofstream

    readJPGStreamwrite_JPEG_file里面的实现除了osg::Image的转换,调用的都是jpeg的第三方库进行操作,这里不去分析。

  • 相关阅读:
    控制语句
    (小程序)接收用户键盘输入
    运算符
    java doc形成注释文档
    linux中rz、sz命令,zip、unzip命令,sqlite3基本操作
    hash应用-加随机盐保存密码
    非对称/对称加密算法,hash算法
    自签名的应用--数字货币
    HTTPS原理
    Django中app的model相互引用问题
  • 原文地址:https://www.cnblogs.com/lyggqm/p/14272604.html
Copyright © 2020-2023  润新知