Jpeglib使用指南, 各种压缩包的压缩和解压方法, 开源社区分裂史

http://antkillerfarm.github.io/

Jpeglib使用指南

1.问题的由来

Jpeg图片在图像处理领域已经用的相当广泛了。但在编程领域,尤其是嵌入式编程领域使用的还不是很广。主要的原因是Jpeg的数据结构和算法远较bmp复杂,非图像算法的专业人士,通常是无法理解这些的。(我有个同事,他曾经花了半个月,研究过Jpeg的原理,还为此在team内部举办了一个讲座,讲了足足有一个小时,令众人对之仰慕万分,但他却说,仅得皮毛,未得要害。从此我对Jpeg的原理敬而远之。)

近来,因工作需要,要在wince平台下,为程序添加Jpeg支持。一般来说,此类问题最容易的解决方案是使用OS提供的相关库,毕竟现在不支持Jpeg的OS几乎没有。但在wince下这里出了个问题。目前绝大多数的wince设备是wince 4.X或5.X的,不过碰巧在图像处理这块,5.X和4.X的方法是不一样的。4.X提供的方法在IMGDECMP.DLL中,而5.X提供的方法在Imaging.DLL中,而且不止是链接库不同,库的接口也是完全两样的。因此,如果软件采用OS提供的相关库的话,在这里就要准备两套接口,非常的麻烦。况且,我们的软件不仅要在wince下部署,将来还打算推广到其他的平台,因此这种方案显然是不太好的。

这时我想到了JpegLib。JpegLib是Independent JPEG Group——一个非Jpeg官方组织推出的Jpeg库。这是个开源免费的库,支持多种平台和编译器,你可以在www.ijg.org中获得它的最新版本。在PC上它的效率比不了intel的Jpeg库,因为后者进行了汇编优化。但在wince上应该和系统库的效率相当。事实上如果查看系统的版权信息的话,Microsoft在wince中也使用了这个库。RISC的芯片也基本没有汇编优化的问题。

网上的中文资料以以下两篇文章最为详尽。

http://mobile.winfans.net/ccs/forums/516/PrintPost.aspx (文献A)

http://blog.csdn.net/zhao3728/archive/2007/08/22/1754877.aspx (文献B)

所以我的这篇文章主要作为补遗之用。

2.编译JpegLib库

文献A和B都是使用现成的JpegLib库,这样的库只在特定的平台下才能用,完全体现不出JpegLib的优势。所以掌握编译JpegLib库的方法,是很有必要的。

JpegLib库源代码的组成

1)makefile。JpegLib库中有很多文件名为makefile的文件。它的后缀名表示它所用于的平台或用途。随便打开一个,就可以看到JpegLib库源代码的组成。

2)makefile中LIBSOURCES变量所代表的文件是JpegLib的核心算法部分。

3)makefile中SYSDEPSOURCES变量所代表的文件是JpegLib中负责内存分配的部分。这部分是系统相关的,所以根据需要选用一个就行了。

4)makefile中APPSOURCES变量所代表的文件是JpegLib中提供诸如命令行压缩Jpeg之类的功能的部分,实际上就是一些小工具。不过在编译JpegLib库时,不要将之添加到工程中。

5)makefile中INCLUDES变量所代表的文件是源代码中用到的头文件。不是所有的头文件都被核心算法部分使用到,因此有些头文件在编译JpegLib库时,是不必要的,当然将之添加到工程中也不会出错。

6)makefile中DOCS变量所代表的文件是一些文档、测试用例之类的东西。其中最有用的是example.c,文献A和B的示例最重要的部分,就来自这里。

7)jconfig。JpegLib库中还有很多和makefile类似的jconfig,这是针对不同平台的类型声明。在使用时,应根据需要,将适当的jconfig文件的后缀名改为h。

以上这些内容更详细的说明见JpegLib库的文档,以及

http://blog.csdn.net/axlrosek/archive/2007/03/29/1545496.aspx

VC:不同版本的VC、EVC都差不多,参照文献A的步骤修改相关文件,然后新建一个空工程,然后打开JpegLib中的makefile.vc文件,将2)和3)、5)、7)中的文件添加到工程中。将生成文件的类型定为lib就行了。此外,还需要针对调用的情况选择适当的运行时库,否则可能会出LNK2005错误。

3.使用JpegLib库

JpegLib库的使用参照文献A和B,以及example.c就可以了。但文献A的示例是有问题的。

bmpBuffer[start+i]=pBuffer[0];

应改为

bmpBuffer[start+i]=pBuffer[0][i];

jpeg_read_scanlines(&cinfo, pBuffer, 1)执行之后,扫描线的内容被放到pBuffer[0],而不是pBuffer中,用memcpy将扫描线的内容转移到其他的缓冲区就行了,无需用循环语句。

4.流输入的Jpeg的处理

上面的示例处理的都是从文件读入的Jpeg,在现实中,还存在流输入的Jpeg。在很多PC游戏中,程序的数据都被集中起来放入一个大文件之中,最典型的当属暴雪的mpq文件。当这些文件被读入内存时,就形成了字节流形式的文件。将之存为临时文件,然后再用之前的方法,显然是笨方法。这时可以采用jpeg_arr_src函数来替换jpeg_stdio_src函数。

这一点还可以参考以下文档,不过该文针对的好像是旧版本,使用时要注意。

http://blog.china.com/u/060803/5544/200608/15355.html

各种压缩包的压缩和解压方法

.tar.gz

解压:tar zxvf FileName.tar.gz

压缩:tar zcvf FileName.tar.gz DirName

PS:tar命令对于长选项和短选项的顺序有要求,例如,不覆盖已有文件的选项--skip-old-files:

tar --skip-old-files -zxvf FileName.tar.gz #正确

tar -zxvf --skip-old-files FileName.tar.gz #错误

.tar

解包:tar xvf FileName.tar

打包:tar cvf FileName.tar DirName

(注:tar是打包,不是压缩!)

.gz

解压1:gunzip FileName.gz

解压2:gzip -d FileName.gz

压缩:gzip FileName

.tar.gz 和 .tgz

解压:tar zxvf FileName.Tar.gz

压缩:tar zcvf FileName.Tar.gz DirName

.bz2

解压1:bzip2 -d FileName.bz2

解压2:bunzip2 FileName.bz2

压缩: bzip2 -z FileName

.tar.bz2

解压:tar jxvf FileName.tar.bz2

压缩:tar jcvf FileName.tar.bz2 DirName

.bz

解压1:bzip2 -d FileName.bz

解压2:bunzip2 FileName.bz

.tar.bz

解压:tar jxvf FileName.tar.bz

.Z

解压:uncompress FileName.Z

压缩:compress FileName

.tar.z

解压:tar Zxvf FileName.tar.z

压缩:tar Zcvf FileName.tar.z DirName

.zip

解压:unzip FileName.zip

压缩:zip FileName.zip DirName

.rar

解压:rar x FileName.rar

压缩:rar a FileName.rar DirName

.lha

解压:lha -e FileName.lha

压缩:lha -a FileName.lha FileName

.rpm

解包:rpm2cpio FileName.rpm | cpio -div

.deb

解包:ar p FileName.deb data.Tar.gz | Tar zxf -

万能脚本

解压:sEx x FileName.*

压缩:sEx a FileName.* FileName

sEx只是调用相关程序,本身并无压缩、解压功能,请注意!

sEx请到: http://sourceforge.net/projects/sex下载!

betty

betty是Jeff Pickhardt开发的人工智能助手,可以将英文转换成Linux命令。

安装方法如下:

sudo apt-get install git curl ruby
cd ~
git clone https://github.com/pickhardt/betty
sudo nano ~/.bashrc

在.bashrc末尾添加以下内容:

alias betty="/home/sk/betty/main.rb"

重启终端即可。

使用方法:

betty compress test/ test.tar.gz

开源社区分裂史

有人的地方,就有江湖,开源社区也同样如此。本来一个战壕的弟兄,因为种种原因,而分道扬镳(或者专业一点叫做fork),从而导致社区的分裂,这并不是什么稀罕事。比如最知名的开源软件Linux,在早期的时候,就有所谓的ac分支,也就是Alan Cox发布的分支。只不过Alan Cox没有另起山头,因此这个只算分支,而不算分裂。但本文下面所要讲述的,可就不是这么小打小闹了。

ffmpeg vs libav

2011年的时候,一群ffmpeg开发者,由于对项目管理者(肯定不是Fabrice Bellard,从log可以看出,这位老兄当时已经不管这个项目很多年了。)不满,而另立山头,创建了libav项目。这从两个项目的图标就可以看出来。话说libav的图标其实是ffmpeg早先的图标,只不过图标的创建者加入了libav项目,因此ffmpeg不得不换了一个类似的图标。

应该说libav项目开局时的思路还是比较好的。但ffmpeg毕竟是个老项目,即使因为惯性,也足以继续吸引开发者开发并使用。这从提交的次数就可以看的很明显,从2011年8月(也就是libav起义时)到2012年底,libav提交6600次,而ffmpeg同期提交了16600次!

当然,ffmpeg项目提交的内容实际上有很多都来自libav。Libav开发者指责FFmpeg项目负责人Michael Niedermayer盗用了他们的成果。据说Michael将Libav的代码合并到FFmpeg,让他成为了FFmpeg最大的贡献者,他递交的代码一度占了新增代码的80%。但正是因为有这样的搬运工的存在,使得ffmpeg最终赢得了这场竞争。

2011年的时候,由于Debian的一个维护者,本身加入了libav项目的缘故,导致Debian/Ubuntu这个linux最大的发行版采用了libav。(典型的以权谋私,哈哈)但最终到了2015年,Debian社区在历时一年的讨论之后,还是放弃了libav项目。

结论:ffmpeg胜。一般来说,后来者需要付出更大的努力,才能夺取先行者的领先地位。而ffmpeg在市场领先的情况下,仍采取虚心接纳的策略,基本杜绝了libav胜出的可能性。

OpenOffice vs LibreOffice

同样是2011年,LibreOffice从OpenOffice中fork出来。fork的原因是由于Oracle收购Sun。众所周知,Oracle是仅次于MS的开源社区二号公敌。因此当Google挑头发起LibreOffice项目之后,开发者几乎一边倒的投向LibreOffice,基本没花什么功夫就打垮了OpenOffice。

结论:LibreOffice胜。开源软件的生命力和魅力都在于开源,人心向背是开源软件胜负的根本。

DivX vs Xvid

DivX本来是个开源项目。但有一天,几个项目管理者建立了一个商业公司,出于商业目的,而将其变成了闭源项目。这样一来,就激怒了为该项目无偿贡献代码的开源社区。作为回应,开源社区发起了Xvid项目。

事情的结局有点童话色彩:开源的Xvid最终战胜了不厚道的DivX。但背后的逻辑并没有那么童话。开源软件由于拥有成本为0,天生就是商业软件,尤其是收费商业软件的克星,这其实是经济规律在起作用。一般来说,如果以100分为满分,免费软件只要拿80分,收费软件就没有什么戏了。而开源软件只要拿70分,闭源软件也同样没戏了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值