libjpeg与turbo libjpeg的使用

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;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值