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

目前网络带宽比起以前是快了很多,但对于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的动态库等内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caimouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值