图像解码之一——使用libjpeg解码jpeg图片
libjpeg简介
libjpeg库的数据结构
libjpeg库的使用
1、设置出错处理函数
1:
2:cinfo.err = jpeg_std_error(&jerr.pub);
3:jerr.pub.error_exit = my_error_exit;
4:
5:if (setjmp(jerr.setjmp_buffer)) {
6:
9:jpeg_destroy_decompress(&cinfo);
10:fclose(infile);
11:return 0;
12:}
1:
4:METHODDEF(void)
5:my_error_exit (j_common_ptr cinfo)
6:{
7:
8:my_error_ptr myerr = (my_error_ptr) cinfo->err;
9:
10:
11:
12:(*cinfo->err->output_message) (cinfo);
13:
14:
15:longjmp(myerr->setjmp_buffer, 1);
16:}
2、初始化解码对象
1:
2:jpeg_create_decompress(&cinfo);
3、初始化源数据
1:
2:jpeg_stdio_src(&cinfo, infile);
4、读取jpeg文件的头信息
1:
2:(void) jpeg_read_header(&cinfo, TRUE);
5、设置解码参数
out_color_space:输出的颜色格式,libjpeg定义如下:
1:
2:typedef enum {
3:JCS_UNKNOWN,
4:JCS_GRAYSCALE,
5:JCS_RGB,
6:JCS_YCbCr,
7:JCS_CMYK,
8:JCS_YCCK,
9:#ifdef ANDROID_RGB
10:JCS_RGBA_8888,
11:JCS_RGB_565
12:#endif
13:} J_COLOR_SPACE;
我们可以看出谷歌在Android扩展了几种输出格式,那么如果你需要的颜色格式输出格式libjpeg不支持(比如:YUYV等颜色格式),那么请参考Android对libjpeg的扩展自行修改,不用担心复杂性,实现起来比较easy。请重点研究jdcolor.c文件中的jinit_color_deconverter函数。
scale_num,scale_denom:因为实际的显示设备千变万化,我们可能需要根据实际情况对输出数据进行一些缩放才能够显示。libjpeg支持对输出数据进行缩放(scale),这个变量就是用来设置缩放的参数。目前libjpeg支持1/2,1/4,1/8三种缩放。
mem:可以指定内存管理相关的内容,比如分配和释放内存,指定libjpeg可以使用的最大内存。默认情况下不同的平台下面都有一个libjpeg默认最大可用内存值,比如Android平台上面该值为10000000L(10M),请参考jmemxxxx.c文件中的DEFAULT_MAX_MEM,了解不同平台的默认最大内存值。通过修改mem->pub.max_memory_to_use的值,库的使用者可以自定义libjpeg可以使用的最大内存值。
6、开始解码
1:
2:(void) jpeg_start_decompress(&cinfo);
7、读取解码数据
1:
4:while (cinfo.output_scanline < cinfo.output_height) {
5:
9:(void) jpeg_read_scanlines(&cinfo, buffer, 1);
10:
11:put_scanline_someplace(buffer[0], row_stride);
12:}
8、结束解码
1:
2:(void) jpeg_finish_decompress(&cinfo);
9、释放解码对象
1:
2:
3:
4:jpeg_destroy_decompress(&cinfo);
总结