您的位置:首页 > 其它

libjpeg与turbo libjpeg的使用

2014-05-07 20:56 417 查看
LibJpeg作为常用开源库,已有很多相关介绍。

其中值得一提的是,早先的版本里没有对内存中的Jpeg图像编解码的接口,而是使用Jpeg_stdio_src和jpeg_stdio_dest,这两个都是直接针对File类对象操作,跳过了内存中图像的这一步。有些文章介绍过如何在LibJpeg中添加针对内存图像的解码接口,但是没有人添加过内存图像的编码接口。我直接把原有的jpeg_stdio_dest覆盖成对内存中RGB图像的编码接口,输出为内存中的jpeg图像。

头文件和静态库已上传到CSDN资源库中,源码也已经上传,(添加对内存中Jpeg图像编解码接口的LibJpeg)可以自行编译使用。

不过后来的turbo libjpeg将此问题解决了(上面上传的代码价值也就不大了),我没有去看是不是新版本的LibJpeg也已经完善了这个问题。

turbo libjpeg的价值是利用SIMD指令集,加速了编解码过程。官网上的介绍中提到某个案例中从原来的0.3左右降低到0.1,时间只有原来的1/3,在我的工程中,时间减少到原来LibJpeg的一半左右。而它的使用与之前的LibJpeg完全相同,只是添加完善了部分功能,完全可以直接替换,使用很方便。

下面的代码既是使用LibJpeg做编解码的方法,也是Turbo LibJpeg的使用方法(区别仅仅在于jpeg_mem_src和jpeg_mem_dst的使用):

值得注意的是,解码的时候空间是由内部分配的,因为这样能够准确分配内存空间,而不会造成浪费;

但是编码的时候空间需要由外部分配,因为准确的编码后的空间大小不能获知,当然完全可以分配一段和编码前一样大小的空间,这肯定是足够的了,并且也不会造成太大的空间浪费。

turbo libjpeg可以在官网上去下载,目前的最新版本是1.3.1.

typedef unsigned char BYTE;
bool ReadJPEG(
/*IN*/BYTE *src, int srcLen,
/*OUT*/BYTE **_dst, int *dstLen, int *width, int *height, int *depth
)
{
// 【注意】dst空间由内部分配
//定义JPEG文件的解压信息
struct jpeg_decompress_struct cinfo;

//定义JPEG文件的错误信息
struct jpeg_error_mgr jerr;

cinfo.err=jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);

jpeg_mem_src(&cinfo,src,srcLen);
jpeg_read_header(&cinfo,TRUE);

jpeg_start_decompress(&cinfo);
(*width) = cinfo.output_width;
(*height) = cinfo.output_height;
(*depth) = cinfo.num_components;
(*dstLen) = (*width)*(*height)*(*depth);
BYTE *dst = new BYTE[*dstLen];

JSAMPROW row_pointer[1];

while (cinfo.output_scanline<cinfo.output_height)
{
row_pointer[0] = &dst[cinfo.output_scanline*cinfo.image_width*cinfo.num_components];
jpeg_read_scanlines(&cinfo,row_pointer,1);
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
*_dst = dst;

return true;
}

bool WriteJPEG(
/*IN*/BYTE *src, int width, int height, int depth,
/*OUT*/BYTE **dst, int *dstLen
)
{
// 【注意】dst空间由外部分配,确保空间足够
unsigned long act_len = 0;
struct jpeg_compress_struct jcs;
struct jpeg_error_mgr jem;
jcs.err = jpeg_std_error(&jem);

jpeg_create_compress(&jcs);
jpeg_mem_dest(&jcs, dst, &act_len);
jcs.image_width = width;
jcs.image_height = height;
jcs.input_components = depth;
jcs.in_color_space = JCS_RGB;

jpeg_set_defaults(&jcs);
jpeg_set_quality(&jcs,80,true);

jcs.jpeg_color_space = JCS_YCbCr;
jcs.comp_info[0].h_samp_factor = 2;
jcs.comp_info[0].v_samp_factor = 2;

jpeg_start_compress(&jcs,TRUE);
JSAMPROW row_pointer[1];
int row_stride = jcs.image_width*jcs.num_components;
while (jcs.next_scanline<jcs.image_height)
{
row_pointer[0] =  &src[jcs.next_scanline*row_stride];
jpeg_write_scanlines(&jcs,row_pointer,1);
}
jpeg_finish_compress(&jcs);
jpeg_destroy_compress(&jcs);

*dstLen = act_len;
return true;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: