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分,閉源軟件也同樣沒戲了。
總結
以上是生活随笔為你收集整理的Jpeglib使用指南, 各种压缩包的压缩和解压方法, 开源社区分裂史的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 这些年微软相关的技术总结, Javasc
- 下一篇: FreeType, FFmpeg, SD