您的位置:首页 > 其它

第二人生的源码分析(五十三) 纹理图片的格式之LLImageJ2C类

2008-05-05 20:58 211 查看
目前网络带宽比起以前是快了很多,但对于3D这样大型程序来说,还是远远不够的。特别像第二人生这样逼真的画面,需要实时传送更多真实细节的图片,既然网络的带宽不够,又需要显示这么逼真的画面,那么只有采用更加先进的技术了。在这里就介绍一下第二人生采用比较新的JPEG2000图片格式。
它的类声明如下:
#001 class LLImageJ2C : public LLImageFormatted
#002 {
#003 protected:
#004 virtual ~LLImageJ2C();
#005
#006 public:
#007 LLImageJ2C();
#008
#009 // Base class overrides

更新图像的数据。
#010 /*virtual*/ BOOL updateData();

下面进行数据解码,也就是变换为RAW的格式。
#011 /*virtual*/ BOOL decode(LLImageRaw *raw_imagep, F32 decode_time=0.0);
#012 /*virtual*/ BOOL decode(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count);

下面从RAW的格式变换为JPEG2000的格式,也就是压缩数据。
#013 /*virtual*/ BOOL encode(const LLImageRaw *raw_imagep, F32 encode_time=0.0);

计算需要内存空间。
#014 /*virtual*/ S32 calcHeaderSize();
#015 /*virtual*/ S32 calcDataSize(S32 discard_level = 0);
#016 /*virtual*/ S32 calcDiscardLevelBytes(S32 bytes);
#017 /*virtual*/ S8 getRawDiscardLevel();
#018

下面添加注释的压缩方式。
#019 // Encode with comment text
#020 BOOL encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time=0.0);
#021

下面检查数据是否有效。
#022 BOOL validate(U8 *data, U32 file_size);

下面是加载JPEG2000的文件。
#023 BOOL loadAndValidate(const LLString &filename);
#024
#025 // Encode accessors
#026 void setReversible(const BOOL reversible); // Use non-lossy?
#027 void setRate(F32 rate);
#028 void setMaxBytes(S32 max_bytes);
#029 S32 getMaxBytes() const { return mMaxBytes; }
#030
#031 static S32 calcHeaderSizeJ2C();
#032 static S32 calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate = 0.f);
#033

下面使用DSO库来实现JPEG2000的数据压缩。
#034 static void openDSO();
#035 static void closeDSO();
#036 static std::string getEngineInfo();
#037
#038 protected:
#039 friend class LLImageJ2CImpl;
#040 friend class LLImageJ2COJ;
#041 friend class LLImageJ2CKDU;
#042 void decodeFailed();
#043 void updateRawDiscardLevel();
#044
#045 S32 mMaxBytes; // Maximum number of bytes of data to use...
#046 S8 mRawDiscardLevel;
#047 F32 mRate;
#048 BOOL mReversible;

下面保存JPEG2000实现压缩的对象。
#049 LLImageJ2CImpl *mImpl;
#050 };
#051

通过这个类可以看到,实现JPEG2000的压缩并不是在这个类里,而是在LLImageJ2Cimpl实现类,这个类也是一个实现组合类,只是一个间接访问的模式。所有的数据压缩和解压,其实都是DSO的库里面,而这个DSO的接口是怎么样的呢?它是通过C++纯虚函数的二进制接口来实现的,现在就去看LLImageJ2Cimpl的声明,就可以知道这个接口是什么样了,它的声明如下:
#001 class LLImageJ2CImpl
#002 {
#003 public:
#004 virtual ~LLImageJ2CImpl();
#005 protected:
#006 // Find out the image size and number of channels.
#007 // Return value:
#008 // true: image size and number of channels was determined
#009 // false: error on decode
#010 virtual BOOL getMetadata(LLImageJ2C &base) = 0;
#011 // Decode the raw image optionally aborting (to continue later) after
#012 // decode_time seconds. Decode at most max_channel_count and start
#013 // decoding channel first_channel.
#014 // Return value:
#015 // true: decoding complete (even if it failed)
#016 // false: time expired while decoding
#017 virtual BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) = 0;
#018 virtual BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
#019 BOOL reversible=FALSE) = 0;
#020
#021 friend class LLImageJ2C;
#022 };

在这个类声明只有三个接口函数getMetadata、decodeImpl和encodeImpl。getMetadata函数是获取图片数据的大小和多少个通道。
decodeImpl函数是把多个通道数据解码为RAW的格式。
encodeImpl函数是把RAW的格式数据压缩为JPEG2000的格式。
下一节再介绍怎么样加载JPEG2000的动态库等内容。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐