为了更好的优化客户端体验,客户端在图像压缩的时候采用了渐进式Jpeg压缩。渐进式Jpeg的好处是,只需要很少的一部分数据包,就能够解码出一副完整的图像,随着数据的增加,图像会不断变清晰。渐进式图像还有一个好处是每一处SOS的Huffman编码都是优化编码,平均图像size会小一些。
对于渐进式Jpeg压缩编码,在libjpeg中设置jpeg_simple_progression(&cinfo);就可以了,这是libjpeg默认的扫描脚本。也可以用自定义的扫描脚本。例如用config_scan_param函数来设定脚本:
bool config_scan_param(j_compress_ptr cinfo)
{
int scanno=0;
jpeg_scan_info * scanptr=NULL;
jpeg_scan_info scans[100];
// 手动填充数组,根据jpegcrush的扫描表
fill_jpegcrush_scan_script(scanno, scans);
if (scanno > 0) {
/* Stash completed scan list in cinfo structure.
* NOTE: for cjpeg's use, JPOOL_IMAGE is the right lifetime for this data,
* but if you want to compress multiple images you'd want JPOOL_PERMANENT.
*/
scanptr = (jpeg_scan_info *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
scanno * sizeof(jpeg_scan_info));
memcpy(scanptr, scans, scanno * sizeof(jpeg_scan_info));
cinfo->scan_info = scanptr;
cinfo->num_scans = scanno;
}
return TRUE;
}
void fill_jpegcrush_scan_script(int & scanno, jpeg_scan_info * scans)
{
scanno = 10;
scans[0].comps_in_scan=1;
scans[0].component_index[0]=0;
scans[0].Ss=0;
scans[0].Se=0;
scans[0].Ah=0;
scans[0].Al=0;
scans[1].comps_in_scan=2;
scans[1].component_index[0]=1;
scans[1].component_index[1]=2;
scans[1].Ss=0;
scans[1].Se=0;
scans[1].Ah=0;
scans[1].Al=0;
scans[2].comps_in_scan=1;
scans[2].component_index[0]=0;
scans[2].Ss=1;
scans[2].Se=8;
scans[2].Ah=0;
scans[2].Al=2;
scans[3].comps_in_scan=1;
scans[3].component_index[0]=1;
scans[3].Ss=1;
scans[3].Se=8;
scans[3].Ah=0;
scans[3].Al=0;
scans[4].comps_in_scan=1;
scans[4].component_index[0]=2;
scans[4].Ss=1;
scans[4].Se=8;
scans[4].Ah=0;
scans[4].Al=0;
scans[5].comps_in_scan=1;
scans[5].component_index[0]=0;
scans[5].Ss=9;
scans[5].Se=63;
scans[5].Ah=0;
scans[5].Al=2;
scans[6].comps_in_scan=1;
scans[6].component_index[0]=0;
scans[6].Ss=1;
scans[6].Se=63;
scans[6].Ah=2;
scans[6].Al=1;
scans[7].comps_in_scan=1;
scans[7].component_index[0]=0;
scans[7].Ss=1;
scans[7].Se=63;
scans[7].Ah=1;
scans[7].Al=0;
scans[8].comps_in_scan=1;
scans[8].component_index[0]=1;
scans[8].Ss=9;
scans[8].Se=63;
scans[8].Ah=0;
scans[8].Al=0;
scans[9].comps_in_scan=1;
scans[9].component_index[0]=2;
scans[9].Ss=9;
scans[9].Se=63;
scans[9].Ah=0;
scans[9].Al=0;
}
这些脚本主要定义了渐进式编码后的图像有多少个SOS,每个SOS包含几个数据分量,以及之后的是DC还是AC数据,具体又是A