嵌入式系统中的数据无损压缩,主要是来源于对于数据传输或者存贮的空间的需求,另外由于嵌入式系统的资源限制,因此对于压缩效率,MIPS和内存的需求是选择一个压缩/解压算法的需要平衡的三个条件.

对于嵌入式系统来说,通常可能在以下一些场合需要使用压缩和解压缩算法:

1)FIRMWARE

2)需要传输或者保存的数据

3)字库的压缩

4)GUI系统的图片的压缩

1)FIRMWARE

对于FIRMWARE的压缩,常用易用的压缩/解压缩算法是ZLIB,这个压缩算法比较好的均衡了压缩率和解压时间,通常,压缩率大概在50%左右,解压的过程大概在1KB/S/MIPS,需要的解压的内存是比较小的,通常在几十KB.

如果你希望获取比ZLIB更高的压缩效率,可以尝试使用LZMA,LZMA对于一般的FIRMWARE的压缩效率比ZLIB要高一些,基本上可以压缩到原大小的1/3左右,但是对于嵌入式系统来说,不要去尝试使用这个压缩工具进行压缩,压缩需要的MIPS和时间是比较长的,基本上低MIPS的系统是很难忍受的,但是解压是另外的一面,解压的速度比ZLIB要慢不少,有时候为了获取高压缩率,这个压缩算法也是可以值得尝试的.

另外一种可以尝试的压缩方法是LZO,压缩率比较低,大概只能压缩到原来的文件大小的2/3,但是它提供了超快的解压速度和0内存需求,实际测试由ADS编译出来的ARM系统的FIRMEWARE解压速度可以到10KB/S/MIPS,也就是说如果你有一个200MHz的CPU,一般情况下你可以在一秒内解压2MB的FIRMWARE,这个对于很多系统来说是足够了.

2)需要传输或者保存的数据

对于类似文本类的或者其它相关性强的数据,如果考虑到存储空间或者传输效率,有时候使用压缩算法也是一个比较好的选择,LZO是首选,当然你也可以使用ZLIB, CMMB的ESG数据就是使用ZLIB进行压缩的.

3)字库的压缩

对于需要使用中文界面的嵌入式系统来说,字库对于整个FIRMWARE大小是贡献比较大的,一般小型的GUI是无法使用矢量字库的,因此常见的情况是使用某个特定大小的字库,如果字库是按照GBK方式进行排序的,那么字库相对来说会小一些,因为GBK是连续的,但是如果使用UNICODE方式排序的字库,那么字库的压缩是一件比较麻烦的事情.

常用的字库的压缩包括了分段法和字库本身的压缩,但是考虑到嵌入式系统的CPU的速度,一般字库本身不大会去压缩.

4)GUI系统的图片的压缩

使用BMP图片对于一个希望用很多图片的系统是蛮可怕的,虽然BMP的DRAW相对很简单,但是实在是太大了.

如果CPU速度还不错,内存也蛮多的,那么PNG的格式应该是个很好的选择,无损,又支持ALPHA

但是对于一些嵌入式系统来说,可能更希望直接能ON TIME DRAW的图像,这些图像在实际的应用中不希望每次都先去解码然后再DRAW,那么可以参考PNG的方式对原始的点阵图像进行压缩,并在DRAW的时候复原图像,由于仅仅使用了简单的算术编码方式,所以DRAW的速度实际上证明也是相当快的,一下是一个DRAW的函数,你应该可以猜出反向的算法:

//直接填充一块RLE图片,need make sure it is the same size
 void CL_RLE_DRAW(unsigned short sx, unsigned short sy, unsigned short width, unsigned short heigh, unsigned short *pGRAM,const unsigned short *pIcon)
 {
 unsigned short i,j;unsigned short Val,Count;
i=0;
 j=0;while(j<heigh)
 {
 Val=*pIcon;
 if(Val&0x8000)
 {
 Count = (Val & 0x7fff) + 1;
 while (Count–)
 {
 *pIcon++;
 Val=pIcon;
 pGRAM[320(sy+j)+(sx+i)] =Val;
 i++;
 if(i==width)
 {
 j++;
 i=0;
 }}
 *pIcon++;}
 else
 {Count=Val+1;
 *pIcon++;Val=pIcon;
 while(Count–)
 {
 pGRAM[320(sy+j)+(sx+i)] =Val;
 i++;
 if(i==width)
 {
 j++;
 i=0;
 }
 }
 *pIcon++;
 }
 }}