- 浏览: 689669 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
lanshui777:
压缩文件里面是空的....
Chrome扩展开发教程 -
seraph炽:
成功!多谢
windows 运行java出现错误:Could not find Java SE Runtime Environment -
canlynet:
应该是国外的网站,被过滤了无法访问。你百度一下就可以看到很多教 ...
python unittest用法 -
草原狙击手:
http://pyunit.sourceforge.net/p ...
python unittest用法 -
fantaxy025025:
现在可以了。thanks!lllt 写道这位哥们,这个写法根本 ...
表格中强制换行和强制不换行(兼容firefox)
libjpeg是一个完全用C语言编写的库,包含了被广泛使用的JPEG解码、JPEG编码和其他的JPEG功能的实现。这个库由独立JPEG工作组维护。最新版本号是6b,于1998年发布。可以参考维基百科关于libjpeg的介绍http://zh.wikipedia.org/wiki/Libjpeg。
libjpeg库的数据结构
用libjpeg库解码jpeg数据的时候,最重要的数据类型为struct jpeg_decompress_struct,一般变量定义成cinfo变量,该变量保存着jpeg数据的详细信息,也保存着解码之后输出数据的详细信息。一般情况下,每次调用libjpeg库API的时候都需要把这个变量作为第一个参数传入。另外用户也可以通过修改该变量来修改libjpeg行为,比如输出数据格式,libjpeg库可用的最大内存等等。
libjpeg库的使用
1、设置出错处理函数
“天有不测风云”,我们使用libjpeg库的时候难免会产生错误,所以我们在使用libjpeg解码之前,首先要做好错误处理。在libjpeg库中,实现了默认错误处理函数,当错误发生时,比如如果内存不足(非常可能发生,后面会介绍)等,则默认错误处理函数将会调用exit函数结束整个进程,详细内容可以参考jerror.c文件。这个对于很多用户来说这样的特性是不合适的,不过libjpeg提供了接口让我们注册自定义错误处理函数。
在C语言中没有C++的异常处理机制,但是提供了setjmp和longjmp机制来实现类似的功能,如果你对这个机制不熟悉的话,请查阅C语言手册。
struct my_error_mgr {
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
};
typedef struct my_error_mgr * my_error_ptr;
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if (setjmp(jerr.setjmp_buffer)) {
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return -1;
}
上述代码中的重点在于我们向libjpeg注册了一个my_error_exit回调函数,当发生错误的时候,该回调函数将会被调用。然后我们调用setjmp函数,设置一个返回点。这样我们在my_error_exit回调函数处理完错误信息之后,就可以调用longjmp函数返回到这里,在这个返回点进行资源的释放(非常重要,否则将会内存泄漏)。我们再看看my_error_exit回调函数的实现:
METHODDEF(void) my_error_exit (j_common_ptr cinfo)
{
my_error_ptr myerr = (my_error_ptr) cinfo->err;
(*cinfo->err->output_message) (cinfo);
longjmp(myerr->setjmp_buffer, 1);
}
可以通过检查cinfo->err->msg_code的值来判断错误类型,进行相应的处理。本例中只是简单的打印一个错误信息。最后调用longjmp跳转到setjmp调用的地方。
2、初始化解码对象
要使用libjpeg解码jpeg数据,这步是必须要做的。
FILE * infile;
if ((infile = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
return -1;
}
jpeg_create_decompress(&cinfo);
这步之后,如果结束解码或者出错之后,需要调用jpeg_destroy_decompress销毁解码对象,否则将会内存泄漏。
3、初始化源数据
在libjpeg库中仅仅提供了文件作为输入数据的接口,在example.c中代码如下:
jpeg_stdio_src(&cinfo, infile);
这个设计我个人觉得非常不合理,我觉得一个友好的库,需要能够接受各式各样的输入(内存数据,网络数据等等)。比较友好的做法是提供几种常用的输入数据支持(在libjpeg中如:文件输入等)。然后还要提供一个用户注册自定义输入函数(回调函数)的接口,这样库就可以适配现实生活中各式各样的输入数据类型了。Simon也在以前的博文中写过怎样修改libjpeg库,使之能够解码内存buffer中的jpeg数据,请参考《LibJpeg解码内存中的Jpeg数据》http://my.unix-center.net/~Simon_fu/?p=565。当然Simon没有扩展libjpeg库让其支持用户注册自定义输入函数(回调函数),有兴趣的朋友可以自行实现。
4、读取jpeg文件的头信息
这个和初始化解码对象一样,是必须要调用的,是约定,没什么好说的。
jpeg_read_header(&cinfo, TRUE);
5、设置解码参数
很多情况下,这步非常重要。比如设置输出格式,设置scale(缩放)等等功能都是在这一步设置。参数设置通过修改上步得到cinfo的值来实现。这里简单介绍一下一些常用的字段。out_color_space:输出的颜色格式,libjpeg定义如下:
typedef enum {
JCS_UNKNOWN, /* error/unspecified */
JCS_GRAYSCALE, /* monochrome */
JCS_RGB, /* red/green/blue */
JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */
JCS_CMYK, /* C/M/Y/K */
JCS_YCCK, /* Y/Cb/Cr/K */
#ifdef ANDROID_RGB
JCS_RGBA_8888, /* red/green/blue/alpha */
JCS_RGB_565 /* red/green/blue in 565 format */
#endif
} 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、开始解码
经过前面的参数设置,我们可以开始解码了,没有什么好说的。
jpeg_start_decompress(&cinfo);
7、读取解码数据(我们打印到终端看看)
buffer = (unsigned char *) malloc(cinfo.output_width * cinfo.output_components);
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, &buffer, 1);
for (i=0; i<cinfo.output_width; i++) {
printf("%02X%02X%02X ", buffer[i*3], buffer[i*3+1], buffer[i*3+2]);
if (0 == ((i+1) % 10) || i == cinfo.output_width-1) {
printf("\n");
}
}
printf("least:%d\n\n", cinfo.output_height-cinfo.output_scanline);
}
请注意虽然函数jpeg_read_scanlines可以指定一次读多少行,但是目前该函数还是只能支持一次只读1行。
8、结束解码
jpeg_finish_decompress(&cinfo);
9、释放解码对象
jpeg_destroy_decompress(&cinfo);
至此一个jpeg数据已经解析完成了。虽然步骤不少但是对于常规的使用还是比较简单的。
总结
libjpeg对于baseline的jpeg数据解码比较好,但是解码progressive的jpeg数据的时候,对内存的需求比较大(我测试过的progressive的图片曾经发现过消耗70M内存)。如果你的硬件能够有硬件解码jpeg的能力,请尽可能使用硬件解码jpeg数据。
简单的说baseline jpeg要全部下载后才能观看;progressive jpeg采用了类似fgs的技术,可以先传个质量粗糙的,然后逐渐精细,直至全部传完。举个例子,浏览有些网页时,看到图片一行行的出现,但都很清晰,一般都是baseline的,而如果开始就是一大块,但就像有好多马赛克似的,看不清楚,然后慢慢就好了,这种一般就是progressive的了
备注:附件里test.rar里面是test.c文件,包含了示例代码,我测试通过了。内存不用设置的时候,也能处理1.68MB的图片,更大的没试过。jpegsrc.v6b.tar.gz是从官网http://sourceforge.net/projects/libjpeg下载的linux上编译通过了的库源码,如果在linux上用,请不要下载官网的.zip文件,那个在linux下面编译会出错。官网下载地址:http://sourceforge.net/projects/libjpeg/files/libjpeg/6b/jpegsrc.v6b.tar.gz/download 打开是个倒计时下载的。
- test.rar (1.1 KB)
- 下载次数: 190
- jpegsrc.v6b.tar.gz (598.9 KB)
- 下载次数: 57
发表评论
-
Linux安装扩展源epel并更新证书
2019-05-14 15:33 624今天更新linux上的软件hddtemp发现一台centos ... -
nodejs安装、模块安装、以及forever让脚本后台运行
2019-02-28 08:40 699centos 安装nodejs: yum install ... -
Linux LVS NAT模式
2019-01-15 14:14 453Linux下使用LVS配置负载均衡十分方便,本文只介绍NA ... -
Centos7 firewalld常用命令
2019-01-10 14:05 565CentOS7使用firewalld代替了iptables ... -
mongodb副本集配置
2019-01-10 09:20 561mongodb的副本集可以很方便的做到数据实时同步到所有主 ... -
使用sync和sesync2进行服务器文件实时同步
2019-01-09 17:00 754主服务器: 192.168.1.8备份服务器: 192.16 ... -
我的firewalld常用命令
2018-12-03 15:12 412添加 firewall-cmd --zone=publ ... -
Linux ssh免密码登录
2017-12-28 14:29 521本机:192.168.1.228 要免密码登陆的远程主机: ... -
Imagemagick转换图片成ico
2017-07-09 06:20 1014Imagemagick是linux、windows、mac下都 ... -
我的.vimrc配置文件
2017-05-13 21:49 524我的.vimrc配置文件 写道 "set mo ... -
Linux中vim的使用
2017-05-13 21:45 926维护linux服务器的时候,大部分时间都在安装服务器端的各种 ... -
linux中利用Libreoffice可将office文档(doc,ppt,xls)转pdf文件
2017-03-18 08:19 3704在有些项目中,或许用户希望上传的word文档,excel表 ... -
centos安装ImageMagick和php的imagick扩展
2017-01-30 18:32 802ImageMagick下载地址: http://www. ... -
mysqld找回消失的InnoDB引擎
2017-01-30 17:01 586闲来无事,在linux服务器上编译安装mysql,成功后停掉 ... -
centos6编译安装apache和php-fpm以及扩展
2017-01-30 10:17 1629首先要下载到apache的源码包,这里我选择下载的是ht ... -
libreoffice将ppt、xls、doc等office文件转换为pdf
2017-01-28 20:20 2019首先要安装libreoffice软件: http://z ... -
centos6 安装或升级svn1.8
2016-12-22 22:19 804参考网址:http://blog.csdn.net/sam ... -
php编译选项
2016-10-31 16:56 441yum install -y pam-devel libc- ... -
git clone的错误fatal: HTTP request failed解决办法
2016-06-24 10:56 6068git clone时可能发生错误,提示:fatal: HT ... -
分治法解决数据最大子段和的问题
2016-04-13 17:47 1933有这么一段数据:int nums[] = {-8, 11, ...
相关推荐
### libjpeg库配置与使用详解 #### 一、libjpeg简介 libjpeg 是一个广泛使用的开源库,主要用于处理 JPEG 图像格式。它支持 JPEG 图像的...掌握 libjpeg 的使用方法对于开发涉及到图像处理的应用程序来说非常重要。
标题中的"libjpeg9a_libjpeg-9a_"提及的是libjpeg库的9a版本,这是一个广泛使用的开源库,主要用于处理JPEG(Joint Photographic Experts Group)图像格式。JPEG是一种常用的有损压缩方法,广泛应用于数码照片和网页...
本文将深入探讨libjpeg9a的核心特性、使用方法以及在微信BlowQme中的应用。 一、libjpeg9a库介绍 libjpeg9a是libjpeg库的一个重要升级,它支持JPEG标准的多种特性,包括基本的YCbCr颜色空间转换、DCT(离散余弦...
JPEG(Joint Photographic Experts Group)是一种广泛使用的图像压缩标准,libjpeg是一个用于处理JPEG图像的C语言库,提供了JPEG编码和解码功能。本文将详细介绍如何使用libjpeg库解码JPEG图片。 首先,要使用...
##### 3.2 libjpeg使用方法 **安装与集成** - 在Linux系统中,可以通过包管理器安装libjpeg库,例如使用`apt-get install libjpeg-dev`命令。 - 在项目中包含必要的头文件并链接libjpeg库。 **基本功能** - **解码...
从网上下载的libjpeg.lib不能直接在C++Builder中使用,这个资源有用C++Builder生成bcb版本的libjpeg.lib的方法,同时还有C++Builder版本下jpeg编解码的函数示例,文件方式和流方式的rgb转jpg,jpg转rgb,jpeg转yv12...
Libjpeg是一个广泛使用的开源库,主要用于JPEG图像编码和解码。在Android开发中,特别是在处理图像相关的应用时,Libjpeg库的运用显得尤为重要。本篇将深入探讨Libjpeg在Android Studio中的集成与使用,帮助开发者更...
libjpeg-turbo是一个高性能的JPEG图像处理库,它是libjpeg的优化版本,特别针对现代处理器的特性进行了优化,尤其是在使用SSE2指令集的x86和x86_64平台上,其速度可以比原版libjpeg快4倍。在Android平台上,libjpeg-...
本篇文章将深入探讨如何在Android NDK环境中使用libjpeg库来解码JPEG图像。 libjpeg是一个广泛使用的开源库,它提供了JPEG图像编码和解码的功能。这个库是用C语言编写的,可以跨平台使用,包括Android系统。在...
对于CV开发者来说,了解libjpeg.so.8的运行机制和报错处理方法至关重要,因为这直接影响到图像处理的效率和程序的稳定性。同时,随着技术的发展,更高版本的libjpeg(如libjpeg-turbo)提供了更好的性能优化,如硬件...
1. **获取Bitmap数据**:使用Bitmap的getPixels()方法或ByteBuffer,提取Bitmap的RGB或ARGB像素数据。注意,Android Bitmap默认的像素存储格式可能不是libjpeg所期望的格式,因此可能需要进行颜色空间转换。 2. **...
在Linux环境中,libjpeg是一个非常重要的库,它用于处理JPEG(Joint Photographic Experts Group)图像格式,这是一种广泛使用的有损压缩方法,尤其适用于照片。libjpeg库提供了对JPEG图像进行编码和解码的功能,...
4. **使用方法** 在Windows环境下,开发人员可以通过设置项目配置,将libjpeg-turbo的库文件路径添加到链接器的输入目录,并将相应的.lib文件加入到依赖库中。对于动态库,还需要确保运行时环境包含对应的.dll文件...
libjpeg 是一个开源的、广泛使用的库,专门用于处理遵循JPEG(Joint Photographic Experts Group)标准的图像文件。 **描述详解:** 这个描述指出,libjpeg_8d 是由独立的JPEG工作组维护的,这意味着这是一个由专业...
在本篇文章中,我们将深入探讨libjpeg库的特性、使用方法以及在Windows环境下与C++的结合。 ### 1. libjpeg库的基本概念 JPEG是一种广泛使用的有损图像压缩格式,主要用于照片和连续色调的图像。libjpeg库由...
在IT领域,图像处理是不可或缺的一部分,而libjpeg是一个广泛使用的开源库,专门用于JPEG(Joint Photographic Experts Group)图像编码和解码。这个库提供了高效且灵活的接口,允许开发者在C语言环境下处理JPEG格式...
通过分析和理解这些代码,你可以学习到libjpeg-turbo库的使用方法,以及JPEG、DIB和BMP格式之间转换的基本原理。这对于进行图像处理、图形编程或开发相关软件都是非常有价值的。在实际应用中,可以根据需求进一步...
libjpeg-turbo是一个JPEG图像编解码器,它使用SIMD指令(MMX、SSE2、AVX2、Neon、AltiVec)来加速x86、x86-64、Arm和PowerPC系统上的基线JPEG压缩和解压缩,以及x86、x86-64和Arm系统上的渐进式JPEG压缩。在这样的系统...
在探讨如何使用LibJPEG库解码内存中的JPEG数据之前,我们先简要回顾一下LibJPEG是什么以及它的主要功能。LibJPEG是一个广泛使用的开源库,用于处理JPEG图像格式。无论是解码(将JPEG文件转换成像素数据)还是编码...